微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Boot资源服务器和Keycloak作用域与角色

如何解决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获得授权。它仅检查声明名称scopescp。但是,正如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 举报,一经查实,本站将立刻删除。