java - Spring Security @PreAuthorize ByPass 用于特定角色
问题描述
我正在使用 Spring 安全策略,需要全局角色SUPER@PreAuthorize
的帮助,当令牌拥有它时,它必须绕过端点上的所有内容。这是一个端点示例:
@GetMapping
@PreAuthorize("(hasAuthority('DOMAIN_FIND_ALL'))")
public ResponseEntity<ResponseDTO<List<DomainDTO>>> findAll() {
return ResponseEntity.ok().body(domainService.findAll());
}
我为我的全球角色找到的工作方式是这样的
@GetMapping
@PreAuthorize("(hasAuthority('DOMAIN_FIND_ALL') or (hasAuthority('SUPER'))")
public ResponseEntity<ResponseDTO<List<DomainDTO>>> findAll() {
return ResponseEntity.ok().body(domainService.findAll());
}
但是实现应用程序的每个端点都太长了(hasAuthority('SUPER')
,所以我正在寻找一种以全局方式配置它的方法,这样,如果令牌具有该角色,则允许所有端点。
我试过的:
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.otherStuffs..
.antMatchers("/**").authenticated()
.antMatchers("/**").hasRole("SUPER");
}
但它不起作用。有人对此有任何想法吗?
解决方案
有关更详细的说明,请查看以下链接(主要是第 6 节)。用作我回复基础的代码是:
CustomMethodSecurityExpressionHandler
以下代码适用于我:
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.otherStuffs..
.antMatchers("/**").authenticated(); // hasRole("SUPER") isn't require
}
覆盖默认MethodSecurityExpressionOperations
接口:
public class MySecurityExpressionRoot implements MethodSecurityExpressionOperations {
// Same properties than provided
// link for MySecurityExpressionRoot
...
public MySecurityExpressionRoot(Authentication authentication) {
if (authentication == null) {
throw new IllegalArgumentException("Authentication object cannot be null");
}
this.authentication = authentication;
}
// This is the ONLY change, as you can see the "SUPER" was added as allowed
@Override
public final boolean hasAuthority(String authority) {
return this.hasAnyAuthority(authority, "SUPER");
}
// Rest of the code is the same than provided
// link for MySecurityExpressionRoot
...
}
现在我们需要将上面的类添加到 Spring 配置中:
@Configuration // Required although not include in "source CustomMethodSecurityExpressionHandler" class
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
final MySecurityExpressionRoot root = new MySecurityExpressionRoot(authentication);
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
return root;
}
}
现在您可以使用以下虚拟GET
端点对其进行验证:
@GetMapping("/add-new-user")
@PreAuthorize("hasAuthority('ADMIN')")
public ResponseEntity<String> addNewUser() {
return new ResponseEntity("[add-new-user] Testing purpose", OK);
}
任何具有:ADMIN
或SUPER
角色的用户都可以访问它。
推荐阅读
- c# - 如何允许此循环调用异步方法
- javascript - 使用参数 mobx-state-tree 执行异步操作
- grid - Orbeon 表单 - 重复网格 - 验证问题
- haskell - Haskell 中的软件事务内存:无法将预期类型 STM a0 与实际类型 IO () 匹配
- gradle - 在gradle中执行curl命令上传文件
- jquery - 如何使用 JQuery Flipbox Slider 在 Magnific Popup 中获取帖子 ID
- c++ - 如何在下面的程序中分配向量?
- php - 安装期间 Symfony 4 和 Sonata News Bundle 错误
- python-3.x - 获取连续行的数据不同的列列表
- firebase - 如何在将图像上传到 Firebase 时等待特定时间