Spring 安全:将 oidc 角色声明提取给 spring 当局
Spring Security: extract oidc role claims to spring authorities
我正在尝试让 OAuth2AuthenticationToken
的角色声明被检测为 Spring 安全机构。 OIDC 提供商端(在我的例子中是 Azure AD)定义了一个自定义角色,它嵌套在 DefaultOidcUser
中,但不会自动添加到权限中:
我试图从 Jwt 令牌中提取它们
但是,当我这样做时,以下方法都没有被调用(无论是在登录期间,还是之后,即使是在默认配置中):
JwtGrantedAuthoritiesConverter.convert(Jwt)
JwtAuthenticationConverter.convert(Jwt)
JwtAuthenticationConverter.extractAuthorities(Jwt)
我当前的配置是:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
<some more config that has nothing to do with oauth/oidc>
.and()
.oauth2Login()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtAuthenticationConverter())
.and()
.and()
.oauth2Client()
;
}
private JwtAuthenticationConverter jwtAuthenticationConverter() {
// create a custom JWT converter to map the roles from the token as granted authorities
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
return jwtAuthenticationConverter;
}
}
我也试过
CustomJwtAuthConverter implements Converter<Jwt, AbstractAuthenticationToken>
但无济于事。
如有任何帮助,我们将不胜感激。
设法使用授权映射器实现它,该映射器还从 oidcToken 中提取声明:
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
[...]
@Bean
public GrantedAuthoritiesMapper userAuthoritiesMapper() {
return authorities -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach(
authority -> {
// Check for OidcUserAuthority because Spring Security 5.2 returns
// each scope as a GrantedAuthority, which we don't care about.
if (authority instanceof OidcUserAuthority) {
OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;
mappedAuthorities.addAll(SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getUserInfo().getClaims()));
mappedAuthorities.addAll(SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getIdToken().getClaims()));
}
}
);
return mappedAuthorities;
};
}
}
在 SecurityUtils 中:
public static List<GrantedAuthority> extractAuthorityFromClaims(Map<String, Object> claims) {
return mapRolesToGrantedAuthorities(getRolesFromClaims(claims));
}
private static List<GrantedAuthority> mapRolesToGrantedAuthorities(Collection<String> roles) {
return roles.stream().filter(role -> role.startsWith("ROLE_")).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
}
之后,自定义角色应该出现在 mappedAuthorities 中,并与它一起出现在令牌的权限中。这样就可以使用注释“hasRole”和“hasAuthority”。
我正在尝试让 OAuth2AuthenticationToken
的角色声明被检测为 Spring 安全机构。 OIDC 提供商端(在我的例子中是 Azure AD)定义了一个自定义角色,它嵌套在 DefaultOidcUser
中,但不会自动添加到权限中:
我试图从 Jwt 令牌中提取它们
但是,当我这样做时,以下方法都没有被调用(无论是在登录期间,还是之后,即使是在默认配置中):
JwtGrantedAuthoritiesConverter.convert(Jwt)
JwtAuthenticationConverter.convert(Jwt)
JwtAuthenticationConverter.extractAuthorities(Jwt)
我当前的配置是:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
<some more config that has nothing to do with oauth/oidc>
.and()
.oauth2Login()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtAuthenticationConverter())
.and()
.and()
.oauth2Client()
;
}
private JwtAuthenticationConverter jwtAuthenticationConverter() {
// create a custom JWT converter to map the roles from the token as granted authorities
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
return jwtAuthenticationConverter;
}
}
我也试过
CustomJwtAuthConverter implements Converter<Jwt, AbstractAuthenticationToken>
但无济于事。
如有任何帮助,我们将不胜感激。
设法使用授权映射器实现它,该映射器还从 oidcToken 中提取声明:
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
[...]
@Bean
public GrantedAuthoritiesMapper userAuthoritiesMapper() {
return authorities -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach(
authority -> {
// Check for OidcUserAuthority because Spring Security 5.2 returns
// each scope as a GrantedAuthority, which we don't care about.
if (authority instanceof OidcUserAuthority) {
OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;
mappedAuthorities.addAll(SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getUserInfo().getClaims()));
mappedAuthorities.addAll(SecurityUtils.extractAuthorityFromClaims(oidcUserAuthority.getIdToken().getClaims()));
}
}
);
return mappedAuthorities;
};
}
}
在 SecurityUtils 中:
public static List<GrantedAuthority> extractAuthorityFromClaims(Map<String, Object> claims) {
return mapRolesToGrantedAuthorities(getRolesFromClaims(claims));
}
private static List<GrantedAuthority> mapRolesToGrantedAuthorities(Collection<String> roles) {
return roles.stream().filter(role -> role.startsWith("ROLE_")).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
}
之后,自定义角色应该出现在 mappedAuthorities 中,并与它一起出现在令牌的权限中。这样就可以使用注释“hasRole”和“hasAuthority”。