将 RoleHierarchy 应用于客户端角色
Apply RoleHierarchy to Client Roles
对于我的应用程序中的安全角色,我们定义了 RoleHierarchy,但是当我们尝试使用 @PreAuthorize("#oauth2.clientHasRole('somerole')")
检查客户端角色时,我们注意到默认情况下我们的 Hirarchy 不适用于客户端角色。
除了在 OAuth2MethodSecurityExpressionHandler
上设置 roleHierarchy 之外,是否还需要一些额外的配置?
正常的 OAuth2MethodSecurityExpressionHandler
不会将 RoleHierarchy 应用于 Client-Authorities。为了解决这个问题,我添加了我自己的 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(...)。
对于我的应用程序中的安全角色,我们定义了 RoleHierarchy,但是当我们尝试使用 @PreAuthorize("#oauth2.clientHasRole('somerole')")
检查客户端角色时,我们注意到默认情况下我们的 Hirarchy 不适用于客户端角色。
除了在 OAuth2MethodSecurityExpressionHandler
上设置 roleHierarchy 之外,是否还需要一些额外的配置?
正常的 OAuth2MethodSecurityExpressionHandler
不会将 RoleHierarchy 应用于 Client-Authorities。为了解决这个问题,我添加了我自己的 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(...)。