[英]How do I use Spring Secuity to secure all CRUD operations?
I am leveraging Spring to create a web application where a PortalUser
can access and create a Ticket
accessible only by their Company
. 我利用Spring创建一个Web应用程序,
PortalUser
可以访问和创建仅可由其Company
访问的Ticket
。
By default, any authenticated user with read/write access can perform all CRUD operations. 默认情况下,任何具有读/写访问权限的经过身份验证的用户都可以执行所有CRUD操作。 The problem is, an authenticated user can perform an operation outside of their
Company
by choosing an id they should not have access to. 问题是,经过身份验证的用户可以通过选择他们不应该访问的ID来在
Company
外部执行操作。
Company Foo could very easily delete, view, etc a ticket from Bar , buy directly accessing the Ticket at example.com/tickets/{any id} Foo公司可以很容易地从Bar删除,查看等票证,可以通过example.com/tickets/{any id}直接购买该票证
@Controller
@RequestMapping("/tickets")
public class TicketController {
@RequestMapping(value = "/{id}", produces = "text/html")
public String TicketController.show(@PathVariable("id") Long id, Model uiModel) {
...
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = "text/html")
public String TicketController.delete(@PathVariable("id") Long id, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel){
...
}
@RequestMapping(method = RequestMethod.GET, produces = "text/html")
public String TicketController.listDatatables(Model uiModel, HttpServletRequest request) {
...
}
}
Without modifying each method in every controller, is there a way to ensure that users cannot access data that is outside of the intended scope? 如果不修改每个控制器中的每个方法,是否有办法确保用户无法访问超出预期范围的数据?
It seems that a custom Filter , could be of use, and I am able to filter out Companies on GET's by cloning and modifying the parameter map, but I haven't found a way solution would work for all methods. 似乎可以使用自定义的Filter ,并且我能够通过克隆和修改参数映射来过滤GET上的Companies,但是我还没有找到一种适用于所有方法的解决方案。
It seems that a way to prevent users from creating or modifying tickets is to add a validator to Ticket
. 看来,一个方法来防止用户创建或修改的票是到一个验证器添加到
Ticket
。
@RooJavaBean
@RooToString
@RooJpaActiveRecord(sequenceName = "TICKET_SEQ", finders = { "findTicketsByCompany", "findTicketsByPerson" })
public class Ticket {
@ValidCompany
Company;
//....
}
We can add the logic to grab the current user's credentials, and check that they are in the same Company
of the Ticket
they are creating / modifying. 我们可以添加逻辑以获取当前用户的凭据,并检查它们是否与他们正在创建/修改的
Ticket
位于同一Company
。
public class CompanyValidator implements ConstraintValidator<ValidCompany, Company> {
@Override
public void initialize(ValidCompany validCompany) {
}
public CompanyValidator() {
}
@Override
public boolean isValid(Company company, ConstraintValidatorContext constraintValidatorContext) {
//logic
Company portalUserCompany = null;
try {
PortalUser portalUser = (PortalUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
portalUserCompany = portalUser.getCompany();
//In this case we are getting the PortalUser's Company, but you could get a user's authorities instead.
} catch (NullPointerException e) {
e.printStackTrace();
}
return portalUserCompany != null && portalUserCompany.getId().equals(company.getId());
}
And the Interface: 和接口:
@Documented
@Constraint(validatedBy = CompanyValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidCompany {
String message() default "{validator.company}";//Error message to be displayed if the CompanyValidator isValid returns false
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.