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

Spring security JHipster-OAuth2/OIDC需要从访问令牌读取组,spring-security,oauth-2.0,jhipster,okta,Spring Security,Oauth 2.0,Jhipster,Okta,JHipster OAuth2/OIDC默认配置要求在idToken中找到“组”。有人能解释如何从访问令牌中读取“组”吗?以下是从访问令牌中检索用户组/授权的更改 注意,在我的例子中,身份验证代码交换的访问令牌(JSON)包含一个“访问令牌”字段作为idToken的对等项。“访问令牌”字段是用户组的实际访问令牌的ID或引用。需要额外的http请求来检索该“实际”访问令牌 对于Okta,访问令牌是一个类似于idToken的JWT,因此,如果出于某种原因,您需要配置Okta将组添加到访问令牌而不是i

JHipster OAuth2/OIDC默认配置要求在idToken中找到“组”。有人能解释如何从访问令牌中读取“组”吗?

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

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

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

解决方案基于此Spring文档:

在WebSecurity配置适配器类中,编辑oauth2Login配置:

.oauth2Login().userInfoEndpoint().oidcUserService(this.oidcUserService());
然后创建自定义oidcUserService():

private OAuth2UserService oidcUserService(){
最终OidcUserService委托=新OIDCUSERVICE();
返回(用户请求)->{
//委托给默认实现以加载用户
OidcUser OidcUser=delegate.loadUser(userRequest);
//访问令牌将是对实际令牌的引用
//(对于Okta,这将是实际的JWT访问令牌)
字符串accessTokenRef=userRequest.getAccessToken().getTokenValue();
//调用端点以获取实际的访问令牌
//(httpClient只是带有所需配置的RestTemplate impl)
String[]groups=httpClient.fetchGroups(accessTokenRef);
//创建授权对象并添加到mappedAuthorities集
Set mappedAuthorities=new HashSet();
用于(字符串组:组){
添加(新的SimpleGrantedAuthority(组));
}
//创建oidcUser的副本,但改用mappedAuthorities
oidcUser=新的DefaultOidcUser(mappedAuthorities,oidcUser.getIdToken(),oidcUser.getUserInfo());
回归方程;
};
}
如果您正在使用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;
    };
}
@Bean
公共授权机构映射器userAuthoritiesMapper(){
返回(权限)->{
Set mappedAuthorities=new HashSet();
集合角色=新HashSet();
权限。forEach(权限->{
roles.add(authority.getAuthority());
});
List List=SecurityUtils.maprolestograndedauthorities(角色);
MappeAuthorities=新哈希集(列表);
返回MappedAuthority;
};
}
可能还有其他方法可以做到这一点,我很乐意听取任何建议。

感谢评论员的帮助。

我正在与Okta合作进行测试,我已将授权服务器配置为将“组”声明添加到访问令牌。生产部署将使用需要“组”的其他身份提供程序“在访问令牌中,我无法在我的开发环境中对该令牌进行测试。好的,我添加了okta标记,以便在默认情况下从ID令牌中读取Spring安全性,从而引起您的注意。也许有办法改变这种状况?我不确定。这是
声明映射到当局的地方。注意:如果您使用JHipster作为资源服务器,在其中传递访问令牌,则会调用JWTDecoderbean,并进行组映射。
@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;
    };
}