Seb*_*ich 2 spring-security oauth-2.0 jwt spring-security-oauth2 keycloak
我的 Spring OAuth2 客户端只向经过身份验证的用户授予ROLE_USER权限,忽略resource_access提供的 JWT 中的权限。
{
"wdb": {
"roles": [
"TestRole",
"TestRoleFoo",
"TestRoleBar"
]
}
Run Code Online (Sandbox Code Playgroud)
如何设置我的 OAuth2 客户端以同时授予来自resource_access(TestRole、TestRoleFoo、TestRoleBar)的权限?我在这里错过了一些关键配置吗?
在我的资源服务器上,我使用具有以下配置的 Springs 默认 OAuth2 客户端:
security:
oauth2:
client:
client-id: wdb
client-secret: some-secret
access-token-uri: http://localhost:8080/auth/realms/master/protocol/openid-connect/token
user-authorization-uri: http://localhost:8080/auth/realms/master/protocol/openid-connect/auth
scope: openid profile email
authorized-grant-types: code
resource:
user-info-uri: http://localhost:8080/auth/realms/master/protocol/openid-connect/userinfo
Run Code Online (Sandbox Code Playgroud)
我的 Keycloak 授权服务器为我提供了以下 JWT 负载:
{
"jti": "6a666808-2b69-4de0-ab94-9ceebdac13de",
"exp": 1569674641,
"nbf": 0,
"iat": 1569674341,
"iss": "http://localhost:8080/auth/realms/master",
"aud": "account",
"sub": "f19b0443-4cce-495a-8479-ff36f82628fc",
"typ": "Bearer",
"azp": "wdb",
"auth_time": 1569674341,
"session_state": "0a411eda-0efb-4f29-99c4-b54da6298d6c",
"acr": "1",
"allowed-origins": [
"/*"
],
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"wdb": {
"roles": [
"TestRole",
"TestRoleFoo",
"TestRoleBar"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid profile email",
"email_verified": true,
"user_name": "sullrich",
"name": "Sebastian Ullrich",
"preferred_username": "sullrich",
"given_name": "Sebastian",
"locale": "de",
"family_name": "Ullrich",
"email": "sebastian@wdb.local"
}
Run Code Online (Sandbox Code Playgroud)
在我的资源服务器中,此 JWT 将派生为以下内容OAuth2Authentication:
{
"authorities":[
{
"authority":"ROLE_USER"
}
],
"details":{
"remoteAddress":"0:0:0:0:0:0:0:1",
"sessionId":"... session id ...",
"tokenValue":"... encoded payload ...",
"tokenType":"bearer"
},
"authenticated":true,
"userAuthentication":{
"authorities":[
{
"authority":"ROLE_USER"
}
],
"details":{
"sub":"f19b0443-4cce-495a-8479-ff36f82628fc",
"email_verified":true,
"user_name":"sullrich",
"name":"Sebastian Ullrich",
"preferred_username":"sullrich",
"given_name":"Sebastian",
"locale":"de",
"family_name":"Ullrich",
"email":"sebastian@wdb.local"
},
"authenticated":true,
"principal":"Sebastian Ullrich",
"credentials":"N/A",
"name":"Sebastian Ullrich"
},
"principal":"Sebastian Ullrich",
"credentials":"",
"clientOnly":false,
"oauth2Request":{
"clientId":"wdb",
"scope":[
],
"requestParameters":{
},
"resourceIds":[
],
"authorities":[
],
"approved":true,
"refresh":false,
"responseTypes":[
],
"extensions":{
}
},
"name":"Sebastian Ullrich"
}
Run Code Online (Sandbox Code Playgroud)
小智 5
听起来您需要自定义 JwtAuthenticationConverter Spring 默认情况下只会将范围映射到授予的权限。
您可以创建一个类来扩展默认实现并覆盖 extractAuthorities 方法。然后您可以访问声明,并且可以将它们映射到您想要的角色。
public class JwtGrantedAuthoritiesConverter extends JwtAuthenticationConverter {
@Override
protected Collection<GrantedAuthority> extractAuthorities(Jwt jwt) {
Collection<GrantedAuthority> authorities = super.extractAuthorities(jwt);
if(jwt.containsClaim("roles") && jwt.getClaimAsStringList("roles").contains("TestRole")) {
authorities.add(new SimpleGrantedAuthority("ROLE_TestRole"));
} else {
.........
}
return authorities;
}
Run Code Online (Sandbox Code Playgroud)
然后将您的版本插入 WebSecurityConfigurationAdapter 中的资源服务器:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
......
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(new JwtGrantedAuthoritiesConverter());
Run Code Online (Sandbox Code Playgroud)
您的角色有点嵌套,即在 resource_access 下。wdb 您始终可以创建一个 keycloak 映射器,将它们添加到父节点中的角色下以简化事情。
这是一个资源服务器的例子,它做类似的事情 https://github.com/wlesniak/effective-oauth2-with-spring-security-and-spring-boot/tree/master/module_8/mod8_support-service
| 归档时间: |
|
| 查看次数: |
779 次 |
| 最近记录: |