mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-29 21:58:52 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			123 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| = OAuth 2.0 Resource Server Bearer Tokens
 | |
| 
 | |
| [[webflux-oauth2resourceserver-bearertoken-resolver]]
 | |
| == 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:
 | |
| 
 | |
| .Custom Bearer Token Header
 | |
| ====
 | |
| .Java
 | |
| [source,java,role="primary"]
 | |
| ----
 | |
| ServerBearerTokenAuthenticationConverter converter = new ServerBearerTokenAuthenticationConverter();
 | |
| converter.setBearerTokenHeaderName(HttpHeaders.PROXY_AUTHORIZATION);
 | |
| http
 | |
|     .oauth2ResourceServer(oauth2 -> oauth2
 | |
|         .bearerTokenConverter(converter)
 | |
|     );
 | |
| ----
 | |
| 
 | |
| .Kotlin
 | |
| [source,kotlin,role="secondary"]
 | |
| ----
 | |
| 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 `{security-api-url}org/springframework/security/oauth2/server/resource/web/reactive/function/client/ServerBearerExchangeFilterFunction.html[ServerBearerExchangeFilterFunction]`, which you can see in the following example:
 | |
| 
 | |
| ====
 | |
| .Java
 | |
| [source,java,role="primary"]
 | |
| ----
 | |
| @Bean
 | |
| public WebClient rest() {
 | |
|     return WebClient.builder()
 | |
|             .filter(new ServerBearerExchangeFilterFunction())
 | |
|             .build();
 | |
| }
 | |
| ----
 | |
| 
 | |
| .Kotlin
 | |
| [source,kotlin,role="secondary"]
 | |
| ----
 | |
| @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 `{security-api-url}org/springframework/security/oauth2/core/AbstractOAuth2Token.html[AbstractOAuth2Token]` credential.
 | |
| Then, it will propagate that token in the `Authorization` header.
 | |
| 
 | |
| For example:
 | |
| 
 | |
| ====
 | |
| .Java
 | |
| [source,java,role="primary"]
 | |
| ----
 | |
| this.rest.get()
 | |
|         .uri("https://other-service.example.com/endpoint")
 | |
|         .retrieve()
 | |
|         .bodyToMono(String.class)
 | |
| ----
 | |
| 
 | |
| .Kotlin
 | |
| [source,kotlin,role="secondary"]
 | |
| ----
 | |
| this.rest.get()
 | |
|         .uri("https://other-service.example.com/endpoint")
 | |
|         .retrieve()
 | |
|         .bodyToMono<String>()
 | |
| ----
 | |
| ====
 | |
| 
 | |
| Will invoke the `https://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
 | |
| [source,java,role="primary"]
 | |
| ----
 | |
| this.rest.get()
 | |
|         .uri("https://other-service.example.com/endpoint")
 | |
|         .headers(headers -> headers.setBearerAuth(overridingToken))
 | |
|         .retrieve()
 | |
|         .bodyToMono(String.class)
 | |
| ----
 | |
| 
 | |
| .Kotlin
 | |
| [source,kotlin,role="secondary"]
 | |
| ----
 | |
| 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.
 | |
| 
 | |
| [NOTE]
 | |
| Unlike the https://docs.spring.io/spring-security/site/docs/current-SNAPSHOT/api/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.html[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.
 |