Spring Security @PreAuthorize ByPass 针对特定角色

问题描述 投票:0回答:2

我正在使用 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");
}

但这不起作用。有人对此有什么想法吗?

java spring spring-security authorization
2个回答
0
投票

更详细的解释,请看下面的链接(主要是第6节)。用作我回复基础的代码是:

我的安全表达式根

自定义方法安全表达式处理程序

以下代码对我有用:

@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
角色的用户都可以访问它。


0
投票

好吧,这是一个棘手的方法:

  1. 在您的项目中创建一个包
    org.springframework.security.authorization.method
  2. 创建类
    PreAuthorizeAuthorizationManager
    ,复制spring源代码,这将覆盖spring源代码。
  3. 在检查功能中,检查用户角色并返回
    AuthorizationDecision
override fun check(authentication: Supplier<Authentication>, mi: MethodInvocation): AuthorizationDecision? {
    // Bypass super admin role, add your own logic here.
    authentication.get().takeIf { it.isAuthenticated }?.let { it.principal as? LoginUserDetails }
        ?.takeIf { it.type === UserType.BACKEND_USER && it.roles.contains("super-admin") }
        ?.let { AuthorizationDecision(true) }
        ?.also { return it }

    // below is spring security original code...
    val attribute = registry.getAttribute(mi)
    if (attribute === ExpressionAttribute.NULL_ATTRIBUTE) {
        return null
    }
    val ctx = registry.expressionHandler.createEvaluationContext(authentication, mi)
    return ExpressionUtils.evaluate(attribute.expression, ctx) as AuthorizationDecision
}
© www.soinside.com 2019 - 2024. All rights reserved.