【问题标题】:jhipster Reload OIDC token after modifying user last name with keycloak rest admin API (Oauth2)使用 keycloak rest admin API (Oauth2) 修改用户姓氏后 jhipster 重新加载 OIDC 令牌
【发布时间】:2020-12-08 00:37:21
【问题描述】:

我让 Jhipster 使用 Oauth2 + Keycloak 运行。

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

问题是需要将信息重新提取到 OIDC 令牌才能让用户立即看到更改。 (类似问题:https://github.com/jhipster/generator-jhipster/issues/7398

是否有任何建议如何设置 Spring Security 以便能够使用 Keycloak 的最新信息重新获取/刷新我的令牌,或者任何明确的调用来做到这一点?

感谢您的回答!

【问题讨论】:

  • 您好,您找到解决方案了吗?我处于同样的情况,用户通过管理客户端正确更新,但 Spring 应用程序仍然依赖旧的令牌数据。我正在考虑一个 hacky 解决方案:使访问令牌无效,并让客户端应用程序在第一个用户更新之后发送另一个请求。然后,无效的访问令牌将使应用程序客户端刷新访问令牌,并从更新的令牌同步数据。我正在寻找更好的解决方案,这并不能说服我太多。

标签: spring-security oauth-2.0 jhipster spring-security-oauth2 keycloak-rest-api


【解决方案1】:

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

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

我对 Spring Security 有一个错误的假设,即它在每次调用时都会根据存储在上下文中的实际令牌来验证令牌数据。事实证明,通过更改上下文中的数据,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);
}

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2021-01-20
    • 2020-08-14
    • 2021-04-19
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2021-06-22
    • 2021-07-04
    相关资源
    最近更新 更多