正常的
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(…)如果我需要的话。