I really would not put it here but I am really confused, I want to achieve the following.
I am running
- Java 14
Spring Cloud Gateway
version:Hoxton.SR3
Spring Boot
version:2.2.5.RELEASE
Now I want to integrate security to my Gateway and to all the downstream microservices. Eventually, I decided to go with Firebase as an Identity Provider (IDP). My Angular application will get JWT token from Firebase and send it in every request to Cloud Gateway. So, the Gateway will start to act as a resource server ONLY and that is it.
Here how I tried to give it a go.
Set up and Spring Cloud Gateway
to act like Resource Server at the same time.
Quite well explained here Spring Security Docs.
Here what my configuration looks like
@EnableWebFluxSecurity
public class ResourceServerSecurityConfiguration {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
// @formatter:on
}
}
And application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
jwk-set-uri: https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
issuer-uri: https://securetoken.google.com/{$app.name}
As you see in this YAML I provided the jwk-set-uri and issuer to validate incoming tokens.
At this point, all work quite as accepted. All the requests have to have valid JWT in the Authentication header.
Next,
I want my gateway to use WebClient
and call several services to aggregate data for the frontend.
Here how I am trying to configure my client.
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder()
.filter(new ServletBearerExchangeFilterFunction());
}
As you see It uses ServletBearerExchangeFilterFunction
this is where my real problem comes in.
I already checked that when Spring configuring oauth2ResourceServer it uses NoOpServerSecurityContextRepository
. From what I understand so far that this is exactly a repository that used to register context per request. Also, I understand that it makes sense to use NoOp as we want to be stateless. However what I do not understand how to make ServletBearerExchangeFilterFunction
to work properly and pass downstream my tokens.
I spend now quite a lot of time trying to figure out the correct way of doing this.
Found this: Spring Boot 2 OIDC (OAuth2) client / resource server not propagating the access token in the WebClient
Github: https://github.com/spring-projects/spring-security/issues/7771
And even according to this what I try to do should be legit and possible. Not sure where I am mistaken.