spring-projects / spring-security

Spring Security
http://spring.io/projects/spring-security
Apache License 2.0
8.55k stars 5.79k forks source link

Support extracting nested authorities in JwtGrantedAuthoritiesConverter #15201

Open thomasdarimont opened 3 weeks ago

thomasdarimont commented 3 weeks ago

Expected Behavior

Users should be able to specify a SpEL expression on the JwtGrantedAuthoritiesConverter to extract the granted authorities from a nested claim structure. This helps to reduce the necessary code to extract roles from nested structures in JWT access tokens generated by Keycloak and other OAuth2 authorization servers which expose roles in nested claims.

spring.security.oauth2.resourceserver.jwt.authorities-claim-expression="[realm_access][roles]"

Current Behavior

Currently custom code (custom JwtGrantedAuthoritiesConverter implementation) is required to extract the role "teacher" from the nested JWT claim shown below.

Context

The Keycloak OAuth2 Authorization Server / OpenID Provider generates JWT access_tokens which contain deeply nested roles configuration like the following:

{
  "jti": "85edca8c-a4a6-4a4c-b8c0-356043e7ba7d",
  "exp": 1598079154,
  "nbf": 0,
  "iat": 1598078854,
  "iss": "http://localhost:8080/auth/realms/education",
  "sub": "ef2cbe43-9748-40e5-aed9-fe981e3082d5",
  "typ": "Bearer",
  "azp": "jakarta-school",
  "auth_time": 0,
  "session_state": "f8ab78f8-15ee-403d-8db7-7052a8647c65",
  "acr": "1",
  "realm_access": {
    "roles": [
      "teacher"
    ]
  },
  "resource_access": {
    "jakarta-school": {
      "roles": [
        "create-student-grade",
        "view-student-profile",
        "view-student-grade"
      ]
    }
  },
  "scope": "profile",
  "name": "Edwin M",
  "preferred_username": "edwin",
  "given_name": "Edwin",
  "family_name": "M"
}
CrazyParanoid commented 3 weeks ago

Hi @thomasdarimont. This feature would be very useful. Personally, I feel inconvenienced when I have to write the same code every time to convert authorities. I like the idea of ​​adding a separate property:

spring.security.oauth2.resourceserver.jwt.authorities-claim-expression="[realm_access][roles]"

But for this you will have to extend OAuth2ResourceServerProperties and change OAuth2ResourceServerJwtConfiguration. I hope this feature will be accepted.