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

时间:2016-05-18 15:39:29

标签: java spring spring-mvc spring-security

我正在利用Spring创建一个网络应用程序,PortalUser可以访问并创建Ticket只能由Company访问的网络应用程序。

默认情况下,具有读/写访问权限的任何经过身份验证的用户都可以执行所有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) {
    ...
    }
}

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

似乎custom Filter可能有用,而且我可以通过克隆和修改参数图来过滤GET公司,但我还没找到方法解决方案适用于所有方法。

1 个答案:

答案 0 :(得分:0)

似乎阻止用户创建或修改票证的方法是向Ticket添加验证器。

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

我们可以添加逻辑来获取当前用户的凭据,并检查它们是否与他们正在创建/修改的Company的{​​{1}}相同。

Ticket

接口:

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());

}