Spring Security 实体字段级安全性

Posted

技术标签:

【中文标题】Spring Security 实体字段级安全性【英文标题】:Spring Security entity field level security 【发布时间】:2015-10-05 05:08:54 【问题描述】:

我有一个 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 项目似乎有这种概念,在 here、here 和示例 here 中提到过。然而,它似乎仅限于基于角色的安全性,而不是 @PreAuthorize 提供的完整 SpEL 支持

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

编辑:

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

【问题讨论】:

数据库代理身份验证(模拟)结合列级安全性如何? @NeilMcGuigan 我真的在为这个问题寻找一个应用程序级别的解决方案,你提到的东西是特定于数据库的,它不适用于维护数据库连接池的 Web 应用程序在单个用户下。 您可以 100% 使用池化 @NeilMcGuigan 我并不是真的在寻找数据库级别的解决方案,因为它是一个可移植的 Spring Boot 应用程序,旨在与 mysql 和 PostgreSQL 等类似的应用程序一起工作,并且不需要数据库管理。我没有真正遇到过你提到的概念,你能解释一下它们是如何工作的吗?我目前正在更详细地研究 AspectJ,因为我认为它可以提供解决方案。 【参考方案1】:

我已经设法在 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 中的评论将该类描述为:

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

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

【讨论】:

以上是关于Spring Security 实体字段级安全性的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security

Spring Security教程

使用Spring Security进行权限验证

使用Spring Security进行权限验证

Spring Boot Security 详解

Spring Security