简体   繁体   English

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

[英]JHipster - OAuth2/OIDC need to read groups from access token

The JHipster OAuth2/OIDC default configuration expects the "groups' to be found in the idToken. Can anyone explain how to read the "groups" from the access token instead? JHipster OAuth2/OIDC 默认配置期望在 idToken 中找到“组”。谁能解释如何从访问令牌中读取“组”?

Here are the changes made to retrieve the user's groups / granted authorities from the access token.以下是从访问令牌中检索用户组/授予权限的更改。

Note that for my case the Access Token (JSON) that the auth code is exchanged for contains an "access_token" field as a peer to the idToken.请注意,在我的情况下,交换身份验证代码的访问令牌 (JSON) 包含一个“access_token”字段作为 idToken 的对等方。 The "access_token" field is an ID or reference to the actual access token with the user's groups. “access_token”字段是一个 ID 或对用户组的实际访问令牌的引用。 An extra http request is needed to retrieve that "actual" access token.需要额外的 http 请求来检索“实际”访问令牌。

For Okta the access token is a JWT similar to the idToken so if for some reason you need to configure Okta to add the groups to the access token instead of the idToken you will find them there.对于 Okta,访问令牌是类似于 idToken 的 JWT,因此如果出于某种原因您需要配置 Okta 以将组添加到访问令牌而不是 idToken,您会在那里找到它们。

Solution was based in this Spring doc:解决方案基于此 Spring 文档:

Delegation-based strategy with OAuth2UserService 使用 OAuth2UserService 的基于委托的策略

In your WebSecurityConfigurerAdapter class edit your oauth2Login config:在您的 WebSecurityConfigurerAdapter class 中编辑您的 oauth2Login 配置:

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

Then create the custom 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;
    };
}

If you are using JHipster there will be a GrantedAuthoritiesMapper that will need to be updated to map the authorities passed in directly to your application roles rather than reading them from the idToken.如果您使用 JHipster,则需要将 GrantedAuthoritiesMapper 更新为 map,权限直接传递给您的应用程序角色,而不是从 idToken 读取它们。 Something like:就像是:

@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;
    };
}

There are likely some other ways to do this and I would be happy to hear any advice.可能还有其他方法可以做到这一点,我很乐意听到任何建议。
Thanks to the commenters for their help.感谢评论者的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM