我正在寻找一种方法来授权访问基于角色和数据内容(表行)使用Spring Boot &;JPA
用例如下:
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
表:角色
这是我写的一篇关于在自定义PermissionEvaluator
中使用@Pre/Post注释的旧文章。这似乎是您最好的选择,并且允许您纯粹使用注释而不是自定义查询。当然,只有当查询返回的报告不太多(没有ro.name = 'ROLE_AAA'
过滤器)时,它才会起作用。
然而,在您的情况下,您并没有真正尝试使用hasPermission(filterObject, 'xyz')
语法,因为您的用例是基于角色的,这意味着权限是角色并且已经存在于认证对象(例如权威机构)和数据库(例如report_roles
)中。使用用户角色和报告角色之间的M:N关系,您可以实现一个帮助器来为您执行检查,如下所示:
@RestController
public class ReportsController {
@GetMapping("/reports")
@PostFilter("@reportExpressions.hasAnyRole(filterObject, authentication)")
public List<Report> getReports() {
return new ArrayList<>(List.of(
new Report("Report #1", Set.of("ROLE_AAA", "ROLE_BBB")),
new Report("Report #2", Set.of("ROLE_AAA", "ROLE_CCC"))
));
}
@Component("reportExpressions")
public static class ReportExpressions {
public boolean hasAnyRole(Report report, Authentication authentication) {
Set<String> authorities = AuthorityUtils.authorityListToSet(
authentication.getAuthorities());
return report.getRoles().stream().anyMatch(authorities::contains);
}
}
public static class Report {
private final String name;
private final Set<String> roles;
public Report(String name, Set<String> roles) {
this.name = name;
this.roles = roles;
}
public String getName() {
return name;
}
public Set<String> getRoles() {
return roles;
}
}
}
如果当前用户有ROLE_AAA
,他们将看到两个报告,等等。我的示例使用控制器,但是您可以将相同的注释应用于JPA存储库。