mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-11-04 00:28:54 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			134 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.5 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.
 | 
						|
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:
 | 
						|
 | 
						|
.Custom Bearer Token Header
 | 
						|
[tabs]
 | 
						|
======
 | 
						|
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 have a bearer token, you can pass that to downstream services.
 | 
						|
This is possible with javadoc:org.springframework.security.oauth2.server.resource.web.reactive.function.client.ServerBearerExchangeFilterFunction[]:
 | 
						|
 | 
						|
[tabs]
 | 
						|
======
 | 
						|
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 `WebClient` shown in the preceding example performs requests, Spring Security looks up the current `Authentication` and extract any javadoc:org.springframework.security.oauth2.core.AbstractOAuth2Token[] credential.
 | 
						|
Then, it propagates that token in the `Authorization` header -- for example:
 | 
						|
 | 
						|
[tabs]
 | 
						|
======
 | 
						|
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>()
 | 
						|
----
 | 
						|
======
 | 
						|
 | 
						|
The prececing example invokes the `https://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:
 | 
						|
 | 
						|
[tabs]
 | 
						|
======
 | 
						|
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 falls back and forwards 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.
 | 
						|
====
 |