gpt4 book ai didi

java - 在 Spring Security 中实现大量级联角色和权限的更好方法?

转载 作者:行者123 更新时间:2023-12-05 05:38:56 24 4
gpt4 key购买 nike

因此,我目前正在为我的组织重构后端代码,为将来的升级做准备。它目前运行良好,只是代码变得相当困惑,因为这个组织中存在大量的角色和授权。

所以我们这里的后端堆栈是一个简单的 springboot Rest API,我们使用第三方 Oauth 身份验证提供程序作为我们的安全提供程序。

因此,对于每个传入的请求,我们都有一个 spring 安全过滤器,它从身份验证 header JWT 中获取用户角色,并根据它分配授权。

    List<GrantedAuthority> authorities = new ArrayList<>();
for (Map.Entry<String,Object> role : user.getCustomClaims().entrySet()) {
authorities.add(new SimpleGrantedAuthority((String) user.getCustomClaims().get("role")));
}
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(user.getEmail(), user.getUid(), authorities));
filterChain.doFilter(request, response);

现在“问题”的存在是因为存在的角色和身份验证的数量,8 年前这家公司最初是一家只有 10 名员工的简单初创公司,现在是一家拥有 500 ~ 名员工的中型公司。因此角色和权限的数量呈指数级增长。

以财务部为例,我们目前有5级权限,而且都是级联的。

  • 财务主管
  • 财务管理员
  • 财务 3
  • 财务 2
  • 财务 1

其中Finance Admin拥有Finance 3的所有权限+自己专属的权限等。

其余 API 中的每个端点最终看起来像这样:

@PreAuthorize("hasAuthority('FinanceHead') or hasAuthority('FinanceAdmin') or hasAuthority('Finance3') or hasAuthority('Finance2') or hasAuthority('Finance1')")

许多端点是多部门的,拥有 20 多个 hasAuthorities。不要误会我的意思,这目前工作正常,但改变一个角色变得很痛苦,因为 id 必须搜索所有端点并更改每个端点。有更好的方法吗?

我在想是否可以将 GrantedAuthority 对象重写成这样:

public class GrantedAuthority {
String role; ("Finance","Logistics", etc)
int authLevel; (1,2,3,4,5)
}

这样我就可以为每个主要端点执行 hasRole("Finance") at 然后使用hasAuth(>3) 用于任何其他端点中的每个方法,如下所示:

@PreAuthorize("hasRole('Finance')
@CrossOrigin
@RestController
@RequestMapping("/test")
public class test {

@PreAuthorize("hasAuthority('authLevel > 3')
@GetMapping
public ResponseEntity<String> ping() {
return new ResponseEntity<>("test", HttpStatus.OK);
}
}

有更好的方法吗?

最佳答案

这就是我最终的处理方式,感谢 M. Deinum 向我展示了 Spring Security 中存在分层角色。

所以我所做的就是像这样创建角色层次结构:

@Bean
public RoleHierarchyImpl roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy(
"ROLE_BOSS > ROLE_FINANCE_HEAD > ROLE_FINANCE_ADMIN > ROLE_FINANCE_3 > ROLE_FINANCE_2 > ROLE_FINANCE_1"
return roleHierarchy;
}

private SecurityExpressionHandler<FilterInvocation> webExpressionHandler() {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy());
return defaultWebSecurityExpressionHandler;
}

然后像这样将它们添加到我的安全配置中:

http                   
.authorizeRequests().anyRequest().authenticated()
.expressionHandler(webExpressionHandler())

所以现在而不是

   @PreAuthorize("hasAuthority('FinanceHead') or hasAuthority('FinanceAdmin') or hasAuthority('Finance3') or hasAuthority('Finance2') or hasAuthority('Finance1')")
@GetMapping("/test")
public ResponseEntity<String> test1() {
return new ResponseEntity<>("Test", HttpStatus.OK);
}

我可以走了

@PreAuthorize("hasRole('ROLE_ADMIN_3')")
@GetMapping("/test")
public ResponseEntity<String> test1() {
return new ResponseEntity<>("Test", HttpStatus.OK);
}

如果请求具有以下任何角色:

ROLE_BOSS, ROLE_FINANCE_HEAD, ROLE_FINANCE_ADMIN, ROLE_FINANCE_3 

请求将完成,否则抛出 403。

关于java - 在 Spring Security 中实现大量级联角色和权限的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72810153/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com