代码之家  ›  专栏  ›  技术社区  ›  Laures

将角色层次结构应用于客户端角色

  •  1
  • Laures  · 技术社区  · 6 年前

    对于我的应用程序中的安全角色,我们定义了角色层次结构,但当我们尝试使用 @PreAuthorize("#oauth2.clientHasRole('somerole')") 我们注意到,默认情况下,我们的雇佣关系不适用于客户角色。

    除了在 OAuth2MethodSecurityExpressionHandler ?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Laures    6 年前

    正常的 OAuth2MethodSecurityExpressionHandler 不将角色层级应用于客户端权限。为了解决这个问题,我添加了自己的ExpressionHandler,通过扩展它来实现。

    public class HierarchicalOAuth2MethodSecurityExpressionHandler extends OAuth2MethodSecurityExpressionHandler {
        public HierarchicalOAuth2MethodSecurityExpressionHandler() {
            super();
        }
    
        @Override
        public StandardEvaluationContext createEvaluationContextInternal(Authentication authentication, MethodInvocation mi) {
            StandardEvaluationContext ec = super.createEvaluationContextInternal(authentication, mi);
            ec.setVariable("oauth2roles", new HierarchicalOAuth2SecurityExpressionMethods(authentication, getRoleHierarchy()));
            return ec;
        }
    }
    
    public class HierarchicalOAuth2SecurityExpressionMethods extends OAuth2SecurityExpressionMethods {
    
        private RoleHierarchy roleHierarchy;
        private Authentication authentication;
    
        public HierarchicalOAuth2SecurityExpressionMethods(Authentication authentication, RoleHierarchy roleHierarchy) {
            super(authentication);
            this.authentication = authentication;
            this.roleHierarchy = roleHierarchy;
        }
    
        @Override
        public boolean clientHasAnyRole(String... roles) {
            if (authentication instanceof OAuth2Authentication) {
                OAuth2Request clientAuthentication = ((OAuth2Authentication) authentication).getOAuth2Request();
                Collection<? extends GrantedAuthority> clientAuthorities = roleHierarchy.getReachableGrantedAuthorities(clientAuthentication.getAuthorities());
                if (clientAuthorities != null) {
                    Set<String> roleSet = AuthorityUtils.authorityListToSet(clientAuthorities);
                    for (String role : roles) {
                        if (roleSet.contains(role)) {
                            return true;
                        }
                    }
                }
            }
    
            return false;
        }
    }
    

    现在,我可以选择使用#oauth2roles。clientHasAnyRole(…)如果我需要的话。