Spring Security实体字段级安全性

我有一个Spring MVC应用程序,它提供了一个视图,显示了Customer实体的所有字段,如名称,地址,电话号码等。应用程序具有各种角色,如ROLE_USERROLE_ADMIN 。 具有ROLE_USER用户只能看到客户名称,因为具有ROLE_ADMIN用户可以看到所有客户字段。

目前,我实现此方法的方法是使用Thymeleaf视图,该视图利用SpringSecurityDialect根据用户的角色限制对某些字段的访问:

  

虽然这种方法非常好但感觉不对,但很难测试。 我想针对控制器编写测试,该控制器使用具有不同角色的主体调用控制器方法,例如testViewCustomerAsRoleAdmintestViewCustomerAsRoleUser 。 这是无法validation的,因为控制器将Customer返回到完全填充的视图,并且每个字段都可通过getter访问。

我所追求的是实体级别的某种字段级安全性,我可以使用Spring Security注释:

 @PreAuthorize("hasRole('ROLE_ADMIN')") public String getPhoneNumber() { return phoneNumber; } 

如果在未经授权的情况下尝试访问该字段时,这可能会引发AccessDeniedException ,这将是理想的。

泽西项目似乎有这种概念, 这里提到这里和这里的一个例子。 但它似乎仅限于基于角色的安全性,而不是@PreAuthorize提供的完整SpEL支持

有没有办法或使用Spring Security实现此类事情,我知道安全上下文或SpEL评估上下文在实体中不可用,因为它们不是Spring管理的。 如果没有,是否还有其他方法可以让我实现同样的目标?

编辑:

我不知道内部的Spring Security框架,但似乎可以在ApectJ模式下使用Spring AOP来检测域(实体)类的方法。 这将是获取AccessDecisionManager并传递身份validation(可能从SecurityContextHolder获得)以及域类方法(如果存在)上的注释内容的情况。 有没有人有做这种事情的经验?

我已经设法在AspectJ模式下使用Spring AOP解决了这个问题。 如果启用AspectJ模式并执行编译时或编译加载时,各种Spring注释(如@Transactional@PreAuthorize将适用于任何非Spring托管类,这里有一个非常好的示例: https : //github.com /spring-projects/spring-security/tree/4.0.1.RELEASE/samples/aspectj-jc

您需要确保项目中具有spring-security-aspects依赖关系(如果使用编译时编织,则需要插件)以启用@Secured注释的编织。 尽管AnnotationSecurityAspect中的AnnotationSecurityAspect将该类描述为:

使用适用于JDK 1.5+的Spring Security @Secured注释的具体AspectJ方面。

该类确实编织了其他Spring注释,包括@PreAuthorize@PreFilter@PostAuthorize@PostFilter