我有一个 Spring MVC 应用程序,它提供了一个视图,其中显示了来自Customer
实体,例如姓名、地址、电话号码等。该应用程序具有各种角色,例如ROLE_USER
and ROLE_ADMIN
。用户具有ROLE_USER
只能看到客户名称,因为用户ROLE_ADMIN
可以看到所有客户字段。
目前我实现这一点的方式是使用百里香叶 http://www.thymeleaf.org视图利用了SpringSecurity方言 https://github.com/thymeleaf/thymeleaf-extras-springsecurity根据用户的角色限制对某些字段的访问:
<th:block sec:authorize="hasRole('ROLE_ADMIN')">
<div th:text="${customer.phoneNumber}" />
</th:block>
虽然这工作得很好,但感觉不太对劲,而且很难测试。我想针对控制器编写测试,该测试使用具有不同角色的主体调用控制器方法,例如testViewCustomerAsRoleAdmin
and testViewCustomerAsRoleUser
。这是无法验证的,因为控制器返回Customer
到完全填充的视图,并且每个字段都可以通过吸气剂访问。
我所追求的是实体级别的某种字段级别安全性,我可以在其中使用 Spring Security 注释:
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String getPhoneNumber()
{
return phoneNumber;
}
如果这能提高AccessDeniedException
如果主体未获得授权,则尝试访问该字段时。
泽西项目似乎有提到的这种概念here http://blog.dejavu.sk/2014/02/04/filtering-jax-rs-entities-with-standard-security-annotations/, here https://jersey.java.net/documentation/latest/entity-filtering.html#ef.security.annotations和一个例子here https://github.com/jersey/jersey/blob/master/examples/entity-filtering-security/src/main/java/org/glassfish/jersey/examples/entityfiltering/security/domain/RestrictedSubEntity.java。然而,它似乎仅限于基于角色的安全性,而不是提供的完整 SpEL 支持@PreAuthorize
有没有什么方法或使用 Spring Security 实现此类事情,我知道安全上下文或 SpEL 评估上下文在实体中不可用,因为它们不是 Spring 管理的。如果没有,是否还有其他方法可以让我实现同样的目标?
EDIT:
我对 Spring Security 框架一无所知,但似乎可以在 ApectJ 模式下使用 Spring AOP 来检测域(实体)类的方法。那么这将是一个获得AccessDecisionManager
并传递身份验证(大概是从SecurityContextHolder
)以及域类方法上的注释内容(如果存在)。有没有人有做这类事情的经验?