jhipster使用keycloak rest admin APIOauth2修改用户姓氏后重新加载OIDC令牌

问题描述

我让Jhipster与Oauth2 + Keycloak一起运行。

我有一个用例,需要从Jhipster React UI更新用户的姓氏和名字,因此我通过服务帐户使用Keycloak管理客户端来更新Keycloak中的用户属性。

问题在于需要将信息重新获取到OIDC令牌,以使用户立即看到更改。 (此处类似的问题:https://github.com/jhipster/generator-jhipster/issues/7398

有没有建议如何设置Spring Security以便能够使用最新的信息形式Keycloak或任何明确的调用来重新获取/刷新我的令牌?

感谢answears!

解决方法

因此,从工作流程的角度来看,我能够通过以下方式解决问题:

  1. 通过 Keycloak 管理客户端更改数据
  2. 更改 Spring Security Context 中的数据

我对 spring 安全性有一个错误的假设,即每次调用时它都会根据存储在上下文中的实际令牌验证令牌数据。事实证明,通过更改上下文中的数据,spring security 没有问题,因此在下次登录时,我可以获得与实际数据内联的有效令牌。

这是我能够改变上下文的代码:

    public void updateUserRole(AbstractAuthenticationToken abstractAuthenticationToken)
{
    SecurityUtils.getCurrentUserLogin().flatMap(userRepository::findOneByLogin)
        .ifPresent(user -> {
            Set<Authority> authorities = user.getAuthorities();
            Authority authority = new Authority();
            authority.setName(AuthoritiesConstants.USER);
            authorities.remove(AuthoritiesConstants.INVITED);
            authorities.add(authority);
            user.setAuthorities(authorities);
            this.clearUserCaches(user);
            log.debug("Changed Information for User: {}",user);
        });
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    List<GrantedAuthority> authorities = List.of(new SimpleGrantedAuthority(AuthoritiesConstants.USER));

    Map<String,Object> claims = ((OidcIdToken)((DefaultOidcUser)((OAuth2AuthenticationToken)abstractAuthenticationToken).getPrincipal()).getIdToken()).getClaims();
    String userNameKey = ((OAuth2AuthenticationToken)authentication).getAuthorizedClientRegistrationId();
    String tokenValue = ((OidcIdToken) ((DefaultOidcUser) ((OAuth2AuthenticationToken) abstractAuthenticationToken).getPrincipal()).getIdToken()).getTokenValue();
    Instant issuedAt = ((OidcIdToken) ((DefaultOidcUser) ((OAuth2AuthenticationToken) abstractAuthenticationToken).getPrincipal()).getIdToken()).getIssuedAt();
    Instant expiresAt = ((OidcIdToken) ((DefaultOidcUser) ((OAuth2AuthenticationToken) abstractAuthenticationToken).getPrincipal()).getIdToken()).getExpiresAt();
    OidcIdToken oidcIdToken = new OidcIdToken(tokenValue,issuedAt,expiresAt,claims);
    DefaultOidcUser user = new DefaultOidcUser(authorities,oidcIdToken,"name");
    OAuth2AuthenticationToken oAuth2AuthenticationToken = new OAuth2AuthenticationToken(user,authorities,userNameKey);


    SecurityContextHolder.getContext().setAuthentication(oAuth2AuthenticationToken);
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...