【发布时间】:2015-10-05 05:08:54
【问题描述】:
我有一个 Spring MVC 应用程序,它显示了一个视图,该视图显示了来自 Customer 实体的所有字段,例如姓名、地址、电话号码等。该应用程序具有各种角色,例如 ROLE_USER 和 ROLE_ADMIN。 ROLE_USER 的用户只能看到客户名称,而 ROLE_ADMIN 的用户可以看到所有客户字段。
目前我实现这一点的方式是使用Thymeleaf 视图,该视图利用SpringSecurityDialect 根据用户角色限制对某些字段的访问:
<th:block sec:authorize="hasRole('ROLE_ADMIN')">
<div th:text="${customer.phoneNumber}" />
</th:block>
虽然这工作得很好,但感觉不对,而且很难测试。我想针对控制器编写测试,该控制器使用具有不同角色的主体(例如testViewCustomerAsRoleAdmin 和testViewCustomerAsRoleUser)调用控制器方法。这无法验证,因为控制器将 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,因为我认为它可以提供解决方案。
标签: java spring security spring-mvc spring-security