2

I am currently working on securing an application that utilizes Angular 16 and Spring Boot 3.2 with Keycloak. To achieve this, I have added spring-boot-starter-oauth2-client and spring-boot-starter-oauth2-resource-server dependencies. My goal is to implement the authorization_code flow on the backend without using a public client. Here's my current security configuration:

httpSecurity
    .cors(Customizer.withDefaults())
    .csrf(AbstractHttpConfigurer::disable)
    .authorizeHttpRequests(this::getAuthorizeRequests)
    .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
    .oauth2Login(loginConfig ->
        loginConfig.tokenEndpoint(Customizer.withDefaults()).userInfoEndpoint(Customizer.withDefaults())
    )
    .logout(Customizer.withDefaults())
    .sessionManagement(manager -> manager.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

And my properties:



spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8000/auth/realms/timetable-local

spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8000/auth/realms/my-realm
spring.security.oauth2.client.registration.keycloak.provider=keycloak
spring.security.oauth2.client.registration.keycloak.client-name=my-client
spring.security.oauth2.client.registration.keycloak.client-id=my-client
spring.security.oauth2.client.registration.keycloak.client-secret=secret
spring.security.oauth2.client.registration.keycloak.scope=openid,offline_access,profile
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code

When attempting to access an API endpoint that requires authorization, I encounter a series of HTTP 302 redirects, as follows:

  • My request to http://localhost:8000/api/me results in a 302 response, redirecting to http://localhost:8000/api/oauth2/authorization/keycloak.
  • Accessing http://localhost:8000/api/oauth2/authorization/keycloak leads to another 302 response, this time redirecting to the Keycloak authentication page.
  • The final request to the /auth endpoint is treated as an XHR request.

I am seeking advice on adjusting the Angular and Spring Boot configurations to redirect the browser to the Keycloak login page instead of processing this as an HTTP request. Can anyone provide guidance or share their experiences on how to effectively configure Angular and Spring Boot for this behavior?

Thank you in advance for your assistance.

1
  • Hi. Did you manage to make this work? I'm doing the same thing and I can't figure this out. I have an angular app as the frontend client, a spring cloud gateway that acts as the oauth2 client and some microservices. Commented Aug 21, 2024 at 7:32

1 Answer 1

0

The solution I came to is to change the HTTP status of OAuth2 redirections sent by Spring client: use something in the 2xx range that reaches the single-page application code (instead of the 3xx which are processed by the browser upfront of the app) and that I can follow by setting the window.location.href.

I implemented that in a starter of mine with a custom redirect strategy that I configure on the authorizationEdpoint. This starter eases the configuration of quite a few other features you'll probably want at some point: let the frontend decide where to redirect the user after login, properly provide with cookie CSRF protection (which is mandatory because your frontend is authorized with sessions, not tokens), etc.

As a side note, REST APIs configured as client with oauth2Login poorly scale (security is based on sessions that you'll have to share or restore when switching instances). A recommended alternative is to use a middleware as client whose responsibilities are limited to:

  • maintain sessions
  • drive the authorization code flow
  • store tokens in sessions
  • replace session cookie with access token in session when routing a request from the frontend to a resource server (REST API secured with tokens)

Spring Cloud Gateway with spring-boot-starter-oauth2-client and the TokenRelay= filter is a perfect fit for such an OAuth2 BFF and I wrote a tutorial on Baeldung about that.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your response. I don't really understand why the second request was made, "localhost:8000/api/oauth2/authorization/keycloak". Could you provide me with some materials to understand it better?
/oauth2/authorization/{registrationId} is the standard endpoint for starting an authorization-code flow on a Spring client. If you configure more than one registration, users will be first redirected to page to choose a registration and, only when they click one, will they be redirected to the matching /oauth2/authorization/{registrationId}. This endpoints set some security stuff in the session and then redirects to the authorization server with parameters from the registration conf.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.