OAuth 2.0 Resource Server Bearer Tokens
Bearer Token Resolution
By default, Resource Server looks for a bearer token in the Authorization
header.
However, you can verify this token.
For example, you may have a need to read the bearer token from a custom header.
To do so, you can wire an instance of ServerBearerTokenAuthenticationConverter
into the DSL:
-
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 have a bearer token, you can pass that to downstream services.
This is possible with ServerBearerExchangeFilterFunction
:
-
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 WebClient
shown in the preceding example performs requests, Spring Security looks up the current Authentication
and extract any AbstractOAuth2Token
credential.
Then, it propagates 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>()
The prececing example invokes the other-service.example.com/endpoint
, adding the bearer token Authorization
header for you.
In places where you need to override this behavior, you can supply the header yourself:
-
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 falls back and forwards 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. |