Spring Security实体字段级安全性
我有一个Spring MVC应用程序,它提供了一个视图,显示了Customer
实体的所有字段,如名称,地址,电话号码等。应用程序具有各种角色,如ROLE_USER
和ROLE_ADMIN
。 具有ROLE_USER
用户只能看到客户名称,因为具有ROLE_ADMIN
用户可以看到所有客户字段。
目前,我实现此方法的方法是使用Thymeleaf视图,该视图利用SpringSecurityDialect根据用户的角色限制对某些字段的访问:
虽然这种方法非常好但感觉不对,但很难测试。 我想针对控制器编写测试,该控制器使用具有不同角色的主体调用控制器方法,例如testViewCustomerAsRoleAdmin
和testViewCustomerAsRoleUser
。 这是无法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
。