英文:
How to map authorities in spring-boot OAuth2 client?
问题
我正在构建一个标准的Spring Boot MVC + Thymeleaf + OAuth2应用。到目前为止,我已经添加了oauth2-client库以进行身份验证,但现在我需要授权来保护我的应用程序。
这是否意味着我还需要将其配置为资源服务器?
如果不需要,我应该如何从我的授权服务器将私有声明(在ID令牌中)中的权限映射为角色?
英文:
I'm building a standard spring boot mvc + thymeleaf + Oauth2. So far I added the oauth2-client lib for authentication purpose but now I need authorization to protect my app.
Does it mean I also need to configure it as a resource server?
If not, how can I map authorities from the private claim (in the ID token) my authorization-server puts roles into?
答案1
得分: 1
资源服务器配置已经适应保护 REST 资源。
客户端配置很好,除非您暴露了您的 API。如果是这样,请添加第二个安全过滤器链。有关详细信息,请参阅另一个答案:在 Spring Boot 中使用 Keycloak Spring 适配器 3。
OAuth2 客户端中的权限映射
如我在评论中提到的,Spring Security 文档 总是比 Stackoverflow 上的任何内容更好(当然,除了 Spring Security 团队成员发布的答案)。
请仔细检查您的授权服务器将用户角色放入的声明,并提供权限映射器,可以通过以下两种方式之一实现:
- 明确使用
http.oauth2Login().userInfoEndpoint().userAuthoritiesMapper(userAuthoritiesMapper());
- 作为一个
@Bean
,类型为GrantedAuthoritiesMapper
,应该由 Spring Boot 自动配置
在这两种情况下,映射器的代码是相同的(请仔细检查您的授权服务器中用户角色的声明名称,但它可能是 Azure AD 中的 groups
):
@Bean
GrantedAuthoritiesMapper userAuthoritiesMapper() {
return (authorities) -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach(authority -> {
if (authority instanceof OidcUserAuthority oidcAuth) {
oidcAuth.getIdToken().getClaimAsStringList("groups").forEach(a -> mappedAuthorities.add(new SimpleGrantedAuthority(a)));
} else if (authority instanceof OAuth2UserAuthority oauth2Auth) {
((List<String>) oauth2Auth.getAttributes().getOrDefault("groups", List.of())).forEach(a -> mappedAuthorities.add(new SimpleGrantedAuthority(a)));
}
});
return mappedAuthorities;
};
}
英文:
Resource-server configuration is adapted to secure REST resources.
Client configuration is just fine unless you expose your API. If so, add a second security filter-chain. Details in this other answer: Use Keycloak Spring Adapter with Spring Boot 3
Authorities mapping in OAuth2 client
As mentioned in my comment, Spring-security documentation is always better than whatever one on Stackoverflow could write (but Spring-security team members of course, who happen to post answers)
Double check the claim in which your authorization-server puts user roles into and provide an authorities mapper, either:
- explicitly with
http.oauth2Login().userInfoEndpoint().userAuthoritiesMapper(userAuthoritiesMapper());
- as a
@Bean
of typeGrantedAuthoritiesMapper
which should be auto-configured by spring-boot
In both cases, the code for the mapper is the same (double check the name of the claim for user roles with your authorization-server, but it might be groups
with Azure AD):
@Bean
GrantedAuthoritiesMapper userAuthoritiesMapper() {
return (authorities) -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach(authority -> {
if (authority instanceof OidcUserAuthority oidcAuth) {
oidcAuth.getIdToken().getClaimAsStringList("groups").forEach(a -> mappedAuthorities.add(new SimpleGrantedAuthority(a)));
} else if (authority instanceof OAuth2UserAuthority oauth2Auth) {
((List<String>) oauth2Auth.getAttributes().getOrDefault("groups", List.of())).forEach(a -> mappedAuthorities.add(new SimpleGrantedAuthority(a)));
}
});
return mappedAuthorities;
};
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论