Spring Boot 资源服务器和 Keycloak 范围与角色

nat*_*nft 2 spring-security spring-boot openid-connect keycloak spring-oauth2

有人在使用 Spring Boot 资源服务器和 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",
    "ROLE_USER",
    "offline_access",
    "ROLE_ADMIN",
    "uma_authorization"
  ],
  "name": "Admin Administrator",
  "preferred_username": "admin",
  "given_name": "Admin",
  "family_name": "Administrator",
  "email": "admin@localhost"
}
Run Code Online (Sandbox Code Playgroud)

非常感谢弗雷迪

Chr*_*ten 6

您需要定义一个Converter<Jwt, Collection<GrantedAuthority>>从 Keycloak 中提取角色的函数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());
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这仅提取角色。如果您需要范围角色,请检查 Spring 的默认值JwtGrantedAuthoritiesConverter以获取代码示例。

将其定义在JwtAuthenticationConverter

private JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
    jwtConverter.setJwtGrantedAuthoritiesConverter(new KeycloakGrantedAuthoritiesConverter());
    return jwtConverter;
}
Run Code Online (Sandbox Code Playgroud)

最后在你的中使用它WebSecurityConfigurerAdapter

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            // [...]
            .oauth2ResourceServer()
                .jwt()
                .jwtAuthenticationConverter(jwtAuthenticationConverter());
}
Run Code Online (Sandbox Code Playgroud)