Yury
Yury

Reputation: 13

Local development with Spring Cloud Gateway and Keycloak for frontend developers

I have a problem with local development for our frontend developers in context of security.

Prerequisites:

  1. Frontend App on ReactJS
  2. Keycloak as IdP provider (OpenID Connect)
  3. Standard authorization code flow
  4. Spring Cloud Gateway as IpD client (register with client secret)

In the schems below I drew an approximate situation of what is happening

Click for view current schema

What I am trying to do

  1. Port-forward spring-cloud-api-gateway in kubernetes to 8110 port
  2. Start local web app on ReactJS on http://localhost:3002 port and init auth flow on http://localhost:8110/oauth2/authorization/client-id
  3. Then I redirected to keycloak for entering login / password (in URL there is a redirect_url parameter that lead to http://localhost:8110 or spring-cloud-api-gateway)
  4. After that I redirected to URL in redirect_url param for exchanging ID token for Access / Refresh token and after that session is considered to be created.
  5. Instead of returning to http://localhost:3002 with session in cookies I stay on http://localhost:8110 and I don't know what to do next and how it should work...

The question is

How to set up local development for frontend developers allowing them to login via keycloak and api-gateway in test enviroment? Maybe there are proven schemes on how to do this?

I was trying to use local nginx using some redirect but have no results.

Upvotes: 0

Views: 854

Answers (1)

ch4mp
ch4mp

Reputation: 12825

What I do in similar setup (development or not):

  • serve both UI (most frequently Angular in my case, but happens to be React too) and REST API through a gateway. This removes the need for CORS configuration as, from the browser perspective, all requests have the same origin: the gateway
  • configure spring-cloud-gateway with spring-boot-starter-oauth2-client, oauth2Login and TokenRelay= filter. This a rather simple way to get an OAuth2 BFF storing tokens in session and translating between session authorization (between the front-end and the gateway) and Bearer token authorization (between the gateway and resource server(s))
  • the authorization server (Keycloak) is not served through the gateway as I use it for SSO across several apps and use a gateway instance per app (this setup requires some CORS configuration in Keycloak to allow requests with the gateways as origin)

The authentication sequence (again, whatever the environment, not only in dev) is the following:

  • the gateway exposes an endpoint with the possible options to initiate authorization_code flow (one per authorization server if you have several)
  • the front-end (Angular in this sample, React in this other one) "exits" by setting the window location to an URI on the gateway to initiate an authorization_code flow
  • the gateway redirects to the authorization server (Keycloak or whatever)
  • once the user is authenticated, the authorization server redirects to the gateway with an authorization-code
  • the gateway exchanges the authorization code for tokens and stores this tokens in session
  • the gateway redirects back to the frontend

This last step (step 6 in your drawing, which you seem to have difficulty with) is done with an authentication success handler configured with http.oauth2Login(oauth2 -> oauth2.authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/ui"))). You can put an absolute URI there (I always do and you will have to if you don't want to serve the UI through the gateway).

Note that you probably want to configure an AuthenticationFailureHandler pointing to your React frontend too.

Upvotes: 0

Related Questions