【发布时间】:2021-12-10 22:52:08
【问题描述】:
我正在寻找一种使用 Spring Boot 和 JPA 基于 ROLES 和 DATA CONTENT(表行)授权访问的方法
用例如下:
Given a User with a Role 'ROLE_AAA'
When user fetches data from table 'REPORT'
Then only reports with specific 'REPORT_ROLE' association will be returned
ER
表:角色
| ID | ROLE |
|---|---|
| 1 | ROLE_AAA |
| 2 | ROLE_BBB |
表格:报告
| ID | CONTENT |
|---|---|
| 1 | ... |
| 2 | ... |
| 3 | ... |
| 4 | ... |
| 5 | ... |
表格:report_roles
| REPORT_ID | ROLE_ID |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 1 |
在这种情况下,角色 ROLE_AAA 的用户将只收到 ID 为 1,2 和 5 的报告。
SELECT re.*
FROM report re
JOIN report_role rr
ON re.id = rr.report_id
JOIN role ro
ON ro.id = rr.role_id
WHERE ro.name = 'ROLE_AAA'
我可以使用关联角色表轻松编写查询 (@org.springframework.data.jpa.repository.Query) 加入我想从中获取数据的表,但我觉得我缺少 JPA 或 Spring Security开箱即用的功能。
非常感谢任何设计/实施建议。
更新
由于返回将被分页 (retuning Page<Object> from JPARepository),我认为 PostFiltering 不是这里的选项。
【问题讨论】:
-
Spring Security 应该在 API 级别运行,并且可能不了解 JPA,所以这在这里可能没有帮助。 JPA 对安全性的处理不多,所以我还要说您需要滚动自己的查询。作为替代方案,您可以将查询或返回的实体相交并在那里应用过滤器,但自定义查询可能更容易理解并因此维护方法(实体可能被绕过,查询也可能,例如通过
findById()) . -
我同意托马斯的观点。但是,如果您坚持使用 Spring Security 并且不介意将数据实际读入应用程序,您可以使用
@PostFilter
标签: java spring-boot hibernate jpa spring-security