This article is an AI-assisted translation of the original French content.
Spring Boot 4.1.0 was released on June 10, 2026 and brings some new features. We will focus here on
the new property spring.security.oauth2.resourceserver.jwt.authorities-claim-expressions
which makes it easier to retrieve authorities (user roles) from JWT tokens when they have a somewhat complex structure.
About JWT tokens and Spring Link to heading
A JWT token (JSON Web Token) is a way to transfer a set of claims between two parties over a web protocol (typically HTTP) and to verify their authenticity using a signature. The purpose of the JWT token is to allow a service to check the identity and rights of a user who wants to access a resource, the user’s identity and rights having been verified beforehand by a third-party service (an authorization server, such as Keycloak) that issued the JWT token. The token consists of three parts:
- a header including in particular the token type and the algorithm used for signing (in the
algparameter). - a payload containing the token’s properties in JSON format. A number of keys are standardized but not mandatory,
except notably
exp(the JWT token expiration time). These properties vary and allow transferring information about the user’s identity (email, last name, first name…), their rights and entitlements, or the token audience which designates the service(s) for which the token was generated. The JSON may have a complex multi-level structure with arrays. This justifies the use of SpEL expressions to retrieve entitlements at different levels and/or different locations within the payload. - a signature which corresponds to the signature, according to the algorithm defined in the header, of the base64-encoded header and payload contents concatenated with a
..
When transporting the JWT token, the three parts are base64-encoded and concatenated with a . (dot) as a separator between each part.
This makes it possible to pass the token in an HTTP Authorization header.
When decoding the token, the resource server is responsible for decoding and validating the JWT token before using its information to control user access.
Validation is an essential step to ensure the authenticity of the token; it mainly consists of:
- verifying the signature (using the authorization server’s public key when using an asymmetric encryption algorithm)
- verifying the token audience
- verifying the token expiration date
An example JWT token Link to heading
A token can be represented in plain text with its header and payload in JSON format:
- header:
{
"typ": "JWT",
"alg": "RS256"
}
- payload:
{
"exp": 1781602479,
"iat": 1781602179,
"auth_time": 1781588556,
"iss": "https://example.com/auth/realms/accounts",
"aud": ["green-app", "blue-app"],
"typ": "Bearer",
"realm_access": {
"roles": ["manager_BLUEAPP", "access-granted_FORGE"]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid profile email",
"email_verified": false,
"name": "Fabrice Bibonne",
"preferred_username": "FBibonne",
"given_name": "Fabrice",
"family_name": "Bibonne",
"email": "fabrice.bibonne@courriel.eco"
}
In this case, the token will be signed by an asymmetric encryption algorithm (RSA), so verification will simply be performed by the resource server using the authorization server’s public key.
Spring’s role in all this Link to heading
JWT token handling for the resource server is managed on the Spring Security side in the spring-security-oauth2-jose module, which is a dependency of spring-boot-starter-security-oauth2-resource-server.
Spring Security is responsible for retrieving the JWT token from the incoming HTTP request, decoding it (deserialization + validation), and extracting the useful information to enrich the principal
of the HTTP request being processed. These operations can be tedious to perform manually, which is why the framework’s contribution is essential.
How to use spring.security.oauth2.resourceserver.jwt.authorities-claim-expressions?
Link to heading
Under the hood Link to heading
Spring Security translates JWT tokens as instances of org.springframework.security.oauth2.jwt.Jwt in order to process them.
The SpEL expressions responsible for retrieving entitlements from JWT tokens will operate on these objects. The top-level claims of the Jwt object can be retrieved
through a Map provided by Jwt::getClaims. However, claims at lower levels may be of type com.nimbusds.jose.shaded.gson.JsonElement (nimbus-jose-jwt is the underlying library
on which spring-security-oauth2-jose relies for decoding JWT tokens).
JsonElement types do not support SpEL syntax for indexed types (the element[index] notation). This is why it is better to use get methods supported by both Map
and JsonElement to navigate the payload’s JSON graph.
The property spring.security.oauth2.resourceserver.jwt.authorities-claim-expressions allows instantiating one or more objects of type
org.springframework.security.oauth2.server.resource.authentication.ExpressionJwtGrantedAuthoritiesConverter:
a new instance of ExpressionJwtGrantedAuthoritiesConverter is automatically created by Spring Boot for each SpEL expression when configuring the Spring Security OAuth2 access control layer.
Spring Boot configures Spring Security so that the different SpEL expressions are applied to each JWT to be decoded.
Each SpEL expression must be correctly formed, otherwise the application will not start. Each expression is then applied to the Map resulting from Jwt::getClaims and must return a collection of authorities
(castable to a Collection<String>). A SpEL expression is applied using the method org.springframework.expression.Expression#getValue(java.lang.Object, java.lang.Class<T>) where the root object is the Map of claims
and the target type is java.util.Collection<?>. If the expression evaluation fails, the exception is silently handled (logged at trace level) and an empty list of authorities is returned.
Writing a SpEL expression to retrieve a collection of authorities Link to heading
What is SpEL? Link to heading
Spring Expression Language (SpEL) is an expression language with a syntax close to Java that allows writing expressions that can be applied to a context (possibly over a set of objects) and return a value. It allows manipulating Java objects, calling JDK methods or user-defined methods (static or not). In a Spring context, it also allows manipulating beans from the application context. Expressions are passed to the program as strings and interpreted at runtime.
Qualities of a SpEL expression for processing a JWT Link to heading
In the case of retrieving authorities for a JWT token, the SpEL expression will operate on the token’s claims, i.e., an object of type Map<String, Object> (return value of Jwt::getClaims)
and must return a collection of authorities (castable to a Collection<String>). Since the top-level claims are a Map, it is possible to use the Map indexing operator
to retrieve a value from the key name. For example: #root['roles'] (#root refers to the input Map: it is not mandatory to mention it).
Since lower levels may be objects of type com.nimbusds.jose.shaded.gson.JsonElement, it is preferable to use method names that work on both these objects and Map objects, namely the get method to obtain
a value from a key.
Finally, the returned collection must be of type java.util.Collection<String>: collection elements can be transformed for this purpose using
SpEL’s projection operator. For example: get('roles').![toString()]
These different operations can be chained within a single SpEL expression.
SpEL expression examples Link to heading
To retrieve the authorities from resource_access.account.roles in the example above
Link to heading
get('resource_access').get('account').get('roles').![toString()]
To retrieve the authorities from groups and strip the suffixes in the example above
Link to heading
['realm_access'].get('roles').![toString()].![substring(0, #this.indexOf('_'))]
Providing the list of SpEL expressions in the spring.security.oauth2.resourceserver.jwt.authorities-claim-expressions property
Link to heading
To prevent commas within SpEL expressions from being mistaken for list delimiters by the property parser,
it is preferable to define authorities-claim-expressions as an array.
Case of an application.yaml file
Link to heading
spring:
security:
oauth2:
resourceserver:
jwt:
authorities-claim-expressions:
- "get('resource_access').get('account').get('roles').![toString()]"
- "['groups'].![toString()].![substring(0, #this.indexOf('_'))]"
Case of an application.properties file
Link to heading
spring.security.oauth2.resourceserver.jwt.authorities-claim-expressions[0] = get('resource_access').get('account').get('roles').![toString()]
spring.security.oauth2.resourceserver.jwt.authorities-claim-expressions[1] = ['groups'].![toString()].![substring(0, #this.indexOf('_'))]
No additional code is required Link to heading
The presence of the spring-boot-starter-security-oauth2-resource-server module and the properties are sufficient for Spring Boot to automatically load the Spring Security OAuth2 configuration
for the resource server. The following properties will likely be needed:
spring.security.oauth2.resourceserver.jwt.jwk-set-uri: mandatory (or alternativelyspring.security.oauth2.resourceserver.jwt.issuer-uri)spring.security.oauth2.resourceserver.jwt.authority-prefix: optional, but without a value, the authorities extracted from the JWT will automatically be prefixed withSCOPE_spring.security.oauth2.resourceserver.jwt.audiences: recommended to verify that the JWT token is intended for the right service
Writing a test for SpEL expressions Link to heading
SpEL expressions are only compiled and verified at runtime, and there is therefore no guarantee that they will be correct: this is why it is preferable to write one or more tests to
verify that they compile and that they match the structure of the JWT token. Here is a proposed test for this purpose. The rest of the project contains the property-based configuration
of OAuth2 authentication for the resource server from the JWT token (file src/main/resources/application.yaml), the required Maven dependencies, and the
Main class.
Conclusion Link to heading
- Thanks to Spring Boot 4.1:
- Access control management for a web server via OAuth2 using JWT tokens can be achieved through simple
configuration and without a single line of code, thanks to the
spring-boot-starter-security-oauth2-resource-servermodule - Rights and entitlements are retrieved even when the JWT token structure is complex (multiple levels of Claims and multiple locations) using a single property
- Access control management for a web server via OAuth2 using JWT tokens can be achieved through simple
configuration and without a single line of code, thanks to the
- This saves having to create specific beans such as
JwtAuthenticationConverterand the accompanying configuration code.