java - 将 Realm 角色和资源角色与 Keycloak/SpringSecurity 一起使用
问题描述
我正在尝试在带有 spring-security 和 keycloak 的 java 应用程序中同时使用领域和资源角色。不幸的是,keycloak 将仅根据以下值返回一个或另一个:
keycloak.use-resource-role-mappings=true
您仍然可以使用自定义代码同时获得两者,但它会混淆诸如 @PreAuthorize 或 spring-boot 方法 .isUserInRole 之类的注释,从而导致代码丑陋。
有没有办法覆盖 @PreAuthorize 方法或 JSON 令牌 Keycloak 返回以同时使用领域和资源角色?目前,我的 keyclaok 实现使用自定义方法替换每个方法开头的 @PreAuthorize,它并不漂亮。
先感谢您。
解决方案
当我在 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();
}
感谢您的帮助亚历山大!
推荐阅读
- mysql - SQL 从表中删除查询
- c# - 使用 C# 中的连接字符串连接到我的项目文件夹中的 SQL 数据库
- r - R 在存储在硬盘上的许多数据帧上有效地绑定_rows
- c# - 在 MainWindow 中使用单独的 ViewModel 连接多个 UserControl
- c# - 关闭 C# 控制台应用程序后继续运行 SQL 存储过程
- tensorflow - 我怎样才能让我的模型接受字符串输入
- javascript - 手风琴开关打开 + 减号
- python - 如何解决导入 pygame 期间的错误
- c# - 如何动态添加或删除文本框?
- python - 如何在 Qt 中创建一个基本的自定义 QGraphicsEffect?