Spring Security实体字段级安全性

时间:2015-07-15 22:53:03

标签: java spring security spring-mvc spring-security

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

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

<th:block sec:authorize="hasRole('ROLE_ADMIN')">
  <div th:text="${customer.phoneNumber}" />
</th:block>

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

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

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

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

Jersey项目似乎有这样一个概念,提到了herehere和一个例子here。但它似乎仅限于基于角色的安全性,而不是@PreAuthorize

提供的完整SpEL支持

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

修改

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

1 个答案:

答案 0 :(得分:2)

我设法在AspectJ模式下使用Spring AOP解决了这个问题。如果您启用AspectJ模式并执行编译时或编译加载时,各种Spring注释(例如<a></a><li><a href=''>List item</a></li> //Do not delete <li><a href=''></a></li> //Delete )将适用于任何非Spring托管类,这里有一个非常好的示例:{ {3}}

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

  

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

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