Build and Test Reactive Microservices with Spring Cloud Gateway

Matt Raible

My Get Started with Spring Security 5.0 and OIDC blog post has an example:


@RequestMapping("/userinfo")
public String userinfo(Model model, OAuth2AuthenticationToken authentication) {
OAuth2AuthorizedClient authorizedClient = this.getAuthorizedClient(authentication);
Map userAttributes = Collections.emptyMap();
String userInfoEndpointUri = authorizedClient.getClientRegistration()
.getProviderDetails().getUserInfoEndpoint().getUri();
if (!StringUtils.isEmpty(userInfoEndpointUri)) { // userInfoEndpointUri is optional for OIDC Clients
userAttributes = WebClient.builder()
.filter(oauth2Credentials(authorizedClient)).build()
.get().uri(userInfoEndpointUri)
.retrieve()
.bodyToMono(Map.class).block();
}
model.addAttribute(“userAttributes”, userAttributes);
return “userinfo”;
}

Lakshyajit Laxmikant

@mattraible Cors configuration is not working. Whenever I try to hit the gateway from an angular SPA, I am getting a CORS error.

Lakshyajit Laxmikant

Here is the screenshot of my error
and the CORS configurations. https://uploads.disquscdn.c…
https://uploads.disquscdn.c…

Matt Raible

Hmmm, that’s strange. Maybe you could try configuring CORS with Spring Cloud Gateway’s YAML Configuration instead?

Lakshyajit Laxmikant

Okay…can I go ahead and do it in the .properties file? Or is it better to use application.yml for spring cloud gateway?

Matt Raible

You might be able to, but I don’t know what the syntax looks like.

Lakshyajit Laxmikant

Ok. Will try that and update

Matt Raible

Hello Lakshyajit - I tested the CORS settings today and found issues. If you use the following for the CORS bean, it should work.


@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(List.of(""));
corsConfig.setMaxAge(3600L);
corsConfig.addAllowedMethod("
");
corsConfig.addAllowedHeader("*");

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return source;
}

I updated this post with these changes and added a changelog at the bottom with links to pull requests.

Lakshyajit Laxmikant

Thanks @Matt for the swift response! Will definitely check this out and let you know.

Lakshyajit Laxmikant

Hi Matt. Sorry for the late reply, but thanks again for the update. It worked.

Lakshyajit Laxmikant

How do I create a logout functionality in the same app? And how can I make a request to logout from…say an angular frontend?

Matt Raible

I’m my experience, you need to create a Logout controller that sends an ID token and post logout redirect URL to the client. The the client does a redirect with the parameters. This is how it’s implemented in JHipster. You can read about it in this blog post.

Lakshyajit Laxmikant

@mattraible as I can see, JHipster configuration is not configured in a ‘reactive’ manner. Apart from that, (correct me if I’m wrong), okta doesn’t allow you to logout on the server side - as I tried to invalidate the session using Websession, but when I login again, it creates a new session and doesn’t require sign in.

Matt Raible

JHipster has supported reactive with Spring Boot since v6.8.0. I wrote the Spring Cloud Gateway implementation myself.

My colleague, @disqus_u7ZhPHjjDC, wrote a post on OpenID Connect Logout Options with Spring Boot. I wasn’t able to get this to work in JHipster, that’s why we redirect to the /logout endpoint.

Maralerdene Tumursuh

Hello Matt, I’m implementing microservice project with Spring Cloud. Then added Google Oauth 2.0 feature to my gateway. But can not find configuration about oauthLogin() and authorizationRequestRepository because also i’m using JWT token authentication, it uses cookie based authentcation /not session based/. How to completely configure jwt token and oauthLogin()

Matt Raible

I don’t think you can use Spring Security’s oauth2Login() and not use session cookies. You should use OAuth 2.0 (with uses JWTs) or JWT token authentication, but not both. If you generate a microservices architecture with JHipster and choose OAuth 2.0, your gateway will store the access token in its session and your microservices will be setup as resource servers. This means the communication from your gateway to your microservices will be stateless (w/o cookies), but the communication from your client (Angular, React, Vue) will use be stateful and use cookies. If you want to scale your stateful gateway, we commend using Spring Session and Redis.

Maralerdene Tumursuh

Thank you for quick response Matt. If i understood correctly, when i use oauth2Login() it’s compulsory use session and cookies right? I’m intending to stateless /without session cookie just JWT and OAuth2.0/ micro service application.But when i use Google OAuth2.0 It’s not possible?

Matt Raible

Yes, oauth2Login() uses sessions and cookies. If you want stateless, you can set your backend up with oauth2ResourceServer().jwt() and do the authentication on the client side. However, if you do the authentication on your client, and store your access token in local storage, it’s less secure than doing everything on the server.

Maralerdene Tumursuh

Great, Thanks Matt.

rahul patel

Spring Cloud Gateway CORS block Okta url