JHipster - OAuth2/OIDC 需要从访问令牌中读取组

Posted

技术标签:

【中文标题】JHipster - OAuth2/OIDC 需要从访问令牌中读取组【英文标题】:JHipster - OAuth2/OIDC need to read groups from access token 【发布时间】:2021-07-04 07:29:38 【问题描述】:

JHipster OAuth2/OIDC 默认配置期望在 idToken 中找到“组”。谁能解释如何从访问令牌中读取“组”?

【问题讨论】:

我正在使用 Okta 进行测试,并且我已配置授权服务器以将“组”声明添加到访问令牌。生产部署将使用不同的身份提供者,该身份提供者要求“组”位于访问令牌中,我无法在我的开发环境中针对该提供者进行测试。 好的,我添加了 okta 标签以便你得到他们的关注 Spring Security 默认从 ID 令牌中读取。也许有办法改变它?我不确定。这是groups 声明映射到当局的地方。 github.com/jhipster/generator-jhipster/blob/main/generators/… 注意:如果您使用 JHipster 作为资源服务器,并在其中传入访问令牌,则会调用 JwtDecoder bean 并执行组映射。 【参考方案1】:

以下是从访问令牌中检索用户组/授予权限的更改。

请注意,在我的情况下,交换身份验证代码的访问令牌 (JSON) 包含一个“access_token”字段作为 idToken 的对等方。 “access_token”字段是一个 ID 或对用户组的实际访问令牌的引用。需要额外的 http 请求来检索“实际”访问令牌。

对于 Okta,访问令牌是类似于 idToken 的 JWT,因此如果由于某种原因您需要配置 Okta 以将组添加到访问令牌而不是 idToken,您会在那里找到它们。

解决方案基于此 Spring 文档:

Delegation-based strategy with OAuth2UserService

在您的 WebSecurityConfigurerAdapter 类中编辑您的 oauth2Login 配置:

.oauth2Login().userInfoEndpoint().oidcUserService(this.oidcUserService());

然后创建自定义的oidcUserService():

private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() 
    final OidcUserService delegate = new OidcUserService();
    return (userRequest) -> 
        // Delegate to the default implementation for loading a user
        OidcUser oidcUser = delegate.loadUser(userRequest);

        // The access token will be a reference to the actual token
        // ( for Okta this would be the actual JWT access token )
        String accessTokenRef = userRequest.getAccessToken().getTokenValue();

        // Call the end point to get the actual access_token
        // ( httpClient is just a RestTemplate impl w/the required configs )
        String[] groups = httpClient.fetchGroups(accessTokenRef);

        // Create the GrantedAuthority objs & add to mappedAuthorities set
        Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
        for (String group: groups) 
            mappedAuthorities.add(new SimpleGrantedAuthority(group));
        

        // Create a copy of oidcUser but use the mappedAuthorities instead
        oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo());
        return oidcUser;
    ;

如果您使用 JHipster,则需要更新 GrantedAuthoritiesMapper,以将传入的权限直接映射到您的应用程序角色,而不是从 idToken 中读取它们。比如:

@Bean
public GrantedAuthoritiesMapper userAuthoritiesMapper() 
    return (authorities) -> 
        Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
        Collection<String> roles = new HashSet();
        authorities.forEach(authority -> 
            roles.add(authority.getAuthority());
        );
        List<GrantedAuthority> list = SecurityUtils.mapRolesToGrantedAuthorities(roles);
        mappedAuthorities = new HashSet<GrantedAuthority>(list);
        return mappedAuthorities;
    ;

可能还有其他方法可以做到这一点,我很乐意听取任何建议。 感谢评论者的帮助。

【讨论】:

以上是关于JHipster - OAuth2/OIDC 需要从访问令牌中读取组的主要内容,如果未能解决你的问题,请参考以下文章

15-oauth2+oidc实现Server部分

ASP.NET Core分布式项目实战oauth2 + oidc 实现 server部分

客户端和资源服务器的 Spring OAuth2 XML 配置 [关闭]

JHipster/Angular 配置如何确定它需要使用 index.html 文件?

如何在 Jhipster+ React 应用程序中自定义 GUI

用于 REST 应用程序的 Oauth SSO