For the latest stable version, please use Spring Security 6.3.4! |
OAuth 2.0 Resource Server Bearer Tokens
Bearer Token Resolution
By default, Resource Server looks for a bearer token in the Authorization
header.
This, however, can be customized.
For example, you may have a need to read the bearer token from a custom header.
To achieve this, you can wire an instance of ServerBearerTokenAuthenticationConverter
into the DSL, as you can see in the following example:
-
Java
-
Kotlin
ServerBearerTokenAuthenticationConverter converter = new ServerBearerTokenAuthenticationConverter();
converter.setBearerTokenHeaderName(HttpHeaders.PROXY_AUTHORIZATION);
http
.oauth2ResourceServer(oauth2 -> oauth2
.bearerTokenConverter(converter)
);
val converter = ServerBearerTokenAuthenticationConverter()
converter.setBearerTokenHeaderName(HttpHeaders.PROXY_AUTHORIZATION)
return http {
oauth2ResourceServer {
bearerTokenConverter = converter
}
}
Bearer Token Propagation
Now that you’re in possession of a bearer token, it might be handy to pass that to downstream services.
This is quite simple with ServerBearerExchangeFilterFunction
, which you can see in the following example:
-
Java
-
Kotlin
@Bean
public WebClient rest() {
return WebClient.builder()
.filter(new ServerBearerExchangeFilterFunction())
.build();
}
@Bean
fun rest(): WebClient {
return WebClient.builder()
.filter(ServerBearerExchangeFilterFunction())
.build()
}
When the above WebClient
is used to perform requests, Spring Security will look up the current Authentication
and extract any AbstractOAuth2Token
credential.
Then, it will propagate that token in the Authorization
header.
For example:
-
Java
-
Kotlin
this.rest.get()
.uri("https://other-service.example.com/endpoint")
.retrieve()
.bodyToMono(String.class)
this.rest.get()
.uri("https://other-service.example.com/endpoint")
.retrieve()
.bodyToMono<String>()
Will invoke the other-service.example.com/endpoint
, adding the bearer token Authorization
header for you.
In places where you need to override this behavior, it’s a simple matter of supplying the header yourself, like so:
-
Java
-
Kotlin
this.rest.get()
.uri("https://other-service.example.com/endpoint")
.headers(headers -> headers.setBearerAuth(overridingToken))
.retrieve()
.bodyToMono(String.class)
rest.get()
.uri("https://other-service.example.com/endpoint")
.headers { it.setBearerAuth(overridingToken) }
.retrieve()
.bodyToMono<String>()
In this case, the filter will fall back and simply forward the request onto the rest of the web filter chain.
Unlike the OAuth 2.0 Client filter function, this filter function makes no attempt to renew the token, should it be expired. To obtain this level of support, please use the OAuth 2.0 Client filter. |