繁体   English   中英

如何使用Spring Secuity保护所有CRUD操作?

[英]How do I use Spring Secuity to secure all CRUD operations?

我利用Spring创建一个Web应用程序, PortalUser可以访问和创建仅可由其Company访问的Ticket

默认情况下,任何具有读/写访问权限的经过身份验证的用户都可以执行所有CRUD操作。 问题是,经过身份验证的用户可以通过选择他们不应该访问的ID来在Company外部执行操作。

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) {
    ...
    }
}

如果不修改每个控制器中的每个方法,是否有办法确保用户无法访问超出预期范围的数据?

似乎可以使用自定义的Filter ,并且我能够通过克隆和修改参数映射来过滤GET上的Companies,但是我还没有找到一种适用于所有方法的解决方案。

看来,一个方法来防止用户创建或修改的票是到一个验证器添加到Ticket

@RooJavaBean
@RooToString
@RooJpaActiveRecord(sequenceName = "TICKET_SEQ", finders = { "findTicketsByCompany", "findTicketsByPerson" })
public class Ticket {
    @ValidCompany
    Company;
    //....
}

我们可以添加逻辑以获取当前用户的凭据,并检查它们是否与他们正在创建/修改的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());

}

和接口:

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM