将领域角色和资源角色与 Keycloak/Spring Security 一起使用
Posted
技术标签:
【中文标题】将领域角色和资源角色与 Keycloak/Spring Security 一起使用【英文标题】:Using both Realm roles and ressource roles with Keycloak/SpringSecurity 【发布时间】:2020-05-25 14:12:44 【问题描述】:我正在尝试在带有 spring-security 和 keycloak 的 java 应用程序中同时使用领域和资源角色。不幸的是,keycloak 只会根据 :
的值返回一个或另一个keycloak.use-resource-role-mappings=true
您仍然可以使用自定义代码来获得两者,但它会弄乱诸如@PreAuthorize 或spring-boot 方法.isUserInRole 之类的注释,从而导致代码丑陋。
有没有办法覆盖@PreAuthorize 方法或Keycloak 返回的JSON 令牌,以便同时使用领域和资源角色?目前,我的 keyclaok 实现使用自定义方法替换每个方法开头的 @PreAuthorize,它并不漂亮。
提前谢谢你。
【问题讨论】:
你写了什么样的自定义代码弄乱了注释?您应该能够通过编写自定义 JwtAuthenticationConverter (docs.spring.io/spring-security/site/docs/current/api/org/…) 从存储在 JWT 中的领域和资源角色填充 GrantedAuthority 来实现您想要的 对不起,我对此不是很清楚,注释很好,但它们不可用,因为它们只包含一半的角色,我会尝试覆盖 Jwt 以获得干净解决方案我也在尝试以@PreAuthorize("@KeycloakAuthorize.hasKeycloakRole('role')") 的格式在预授权中使用bean,但到目前为止也没有成功 好的,那么 JwtAuthenticationConverter 可能是您最好的选择,因为您可以简单地访问 JWT 并根据需要填充权限,例如:***.com/questions/58205510/… 我会试试这个并发布解决方案,如果它有效,谢谢:) Np,让我知道它是否有效! :) 【参考方案1】:当我在 SecurityConfig 中使用它时,让它覆盖 KeycloakAuthenticationProvider。这是自定义提供程序的代码
public class CustomKeycloakAuthenticationProvider extends KeycloakAuthenticationProvider
private GrantedAuthoritiesMapper grantedAuthoritiesMapper;
public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper)
this.grantedAuthoritiesMapper = grantedAuthoritiesMapper;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
for (String role : token.getAccount().getRoles())
grantedAuthorities.add(new KeycloakRole(role));
// ADDING THE MODIFICATION AND ENABLING ROLE FROM RESSOURCE
for (String role : token.getAccount().getKeycloakSecurityContext().getToken().getResourceAccess("CustomApplication").getRoles())
grantedAuthorities.add(new KeycloakRole(role));
return new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), mapAuthorities(grantedAuthorities));
private Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities)
return grantedAuthoritiesMapper != null
? grantedAuthoritiesMapper.mapAuthorities(authorities)
: authorities;
@Override
public boolean supports(Class<?> aClass)
return KeycloakAuthenticationToken.class.isAssignableFrom(aClass);
以及SecurityConfig中的修改
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
CustomKeycloakAuthenticationProvider keycloakAuthenticationProvider = CustomKeycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
private CustomKeycloakAuthenticationProvider CustomKeycloakAuthenticationProvider()
return new CustomKeycloakAuthenticationProvider();
感谢亚历山大的帮助!
【讨论】:
谢谢@Taarawa。它帮助我解决了使用领域角色的问题。以上是关于将领域角色和资源角色与 Keycloak/Spring Security 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
Apache Shiro - 自定义 jdbc 领域 - 读取角色/权限