如何解决Spring Boot资源服务器和Keycloak作用域与角色
外面有人在使用Spring Boot Resource Server和Keycloak吗?
我使用
配置了application.properties
spring.security.oauth2.resourceserver.jwt.issuer-uri = http://localhost:9080/auth/realms/<myrealm>
在我的WebSecurityConfigurerAdapter中,我可以使用像
.antMatchers(HttpMethod.GET,"/user/**").hasAuthority("ScopE_read")
但是我不能使用这些角色!
.antMatchers(HttpMethod.GET,"/user/**").hasRole("ADMIN")
该信息在jwt中可用,但是spring某种程度上不使用它。有人知道我在哪里可以找到描述该映射的文档吗? 我以某种方式认为我的脑袋里有一个节点,但是在哪里和哪个节点?
那是我的jwt:
"exp": 1603373908,"iat": 1603373608,"jti": "0b18b386-9f62-4c42-810e-692ccc4ed7d1","iss": "http://localhost:9080/auth/realms/jhipster","aud": "account","sub": "4c973896-5761-41fc-8217-07c5d13a004b","typ": "Bearer","azp": "web_app","session_state": "17411db5-8d50-4f25-b520-9a3e8b19fd67","acr": "1","allowed-origins": [
"*"
],"realm_access": {
"roles": [
"test","ROLE_USER","offline_access","ROLE_ADMIN","uma_authorization"
]
},"resource_access": {
"account": {
"roles": [
"manage-account","manage-account-links","view-profile"
]
}
},"scope": "email profile","email_verified": true,"roles": [
"test","uma_authorization"
],"name": "Admin Administrator","preferred_username": "admin","given_name": "Admin","family_name": "Administrator","email": "admin@localhost"
}```
Thanks a lot
Fredy
解决方法
您需要定义一个从 Keycloak 的 Converter<Jwt,Collection<GrantedAuthority>>
中提取角色的 realm_access
(为简洁起见,省略了空检查):
public class KeycloakGrantedAuthoritiesConverter implements Converter<Jwt,Collection<GrantedAuthority>> {
@Override
public Collection<GrantedAuthority> convert(Jwt source) {
Map<String,Object> realmAccess = source.getClaimAsMap("realm_access");
List<String> roles = (List<String>) realmAccess.get("roles");
return roles.stream()
.map(rn -> new SimpleGrantedAuthority("ROLE_" + rn))
.collect(Collectors.toList());
}
}
请注意,这只会提取角色。如果您需要范围和角色,请查看 Spring 的默认 JwtGrantedAuthoritiesConverter
以获取代码示例。
在 JwtAuthenticationConverter
中定义:
private JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
jwtConverter.setJwtGrantedAuthoritiesConverter(new KeycloakGrantedAuthoritiesConverter());
return jwtConverter;
}
最后在您的 WebSecurityConfigurerAdapter
中使用它:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// [...]
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtAuthenticationConverter());
}
,
这可能是由于Spring Security从JWT令牌解析/提取角色详细信息的方式。例如,在MicroProfile规范中,提到角色列表将从令牌的“ groups”属性中提取。
查看Spring Security中的RoleVoter文档。似乎它希望角色名称专门以 ROLE _ 前缀开头。也许您就是这种情况。
,您尚未包括所使用的版本,但是我对spring-security-oauth2-resource-server 5.2.2.RELEASE有相同的问题。 此方法:
org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter#getAuthorities
默认情况下负责从jwt获得授权。它仅检查声明名称scope
和scp
。但是,正如response所建议的那样,您可以提供一个CustomJwtAuthenticationConverter
并提取角色。
在您的安全配置中,定义jwt身份验证转换器。您可以设置您的索赔名称,以供授权机构转换器使用。
类似以下的方法应该起作用:
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
@Bean
public JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter() {
// You can use setAuthoritiesClaimName method
JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
return jwtGrantedAuthoritiesConverter;
// You can also add your custom converter here
}
@Override
protected void configure(HttpSecurity http) throws Exception {
final JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(this.jwtGrantedAuthoritiesConverter());
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtAuthenticationConverter);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。