Web application using Angular 15 and Keycloak 20.0.5 | Redirects to the login page after a page refresh

171 Views Asked by At

I'm developing a web application using Angular 15 and Spring Boot. As the IAM solution we are using Keycloak(20.0.5). We have created a public client for the web application (web-application). We have deployed the angular application, keycloak and other spring boot microservice in Kubernetes(in a EKS cluster).

Frontend Kubernetes service name - main-frontend-service

Please also note that application and keycloak deployed in different clusters.

Web application URL : http://a************.amazonaws.com/main-frontend

Keycloak URL : http://b************.amazonaws.com/keycloak-service

Now we are facing the issue, as user refresh the page or duplicate the page or try to open the page in a new tag, user is being redirected to the login page.

Please find the following code snippet for the frontend keycloak client related

import {KeycloakService} from "keycloak-angular";
import {environment} from "../../environments/environment";

export function initializeKeycloak(keycloak: KeycloakService) {
  return () => keycloak.init({
    config: {
      url: `${environment.keycloakConfig.url}`,
      realm: `${environment.keycloakConfig.realm}`,
      clientId: `${environment.keycloakConfig.clientId}`,
    },
    initOptions: {
      // checkLoginIframe: true,
      // checkLoginIframeInterval: 300,
      onLoad: 'login-required',
      // silentCheckSsoRedirectUri:
      //   window.location.origin + '/assets/silent-check-sso.html'
    },
  });
}

We have tried the currently suggested solutions for this issue and we were unable to find a solution.

Please find the keycloak client configurations

Root URL : http://a************.amazonaws.com/main-frontend

Redirect URL : /main-frontend

enter image description here

Please also find nginx configurations for main-frontend-service in kubernetes

paths:
- backend:
    service:
      name: main-frontend-service
      port:
        number: 80
  path: /(/|$)(.*)
  pathType: Prefix
- backend:
    service:
      name: main-frontend-service
      port:
        number: 80
  path: /main-frontend(/|$)(.*)
  pathType: Prefix

EDITED

Web application(when up it locally) is working fine in localhost as expected

Please find the current architecture. Were all the backend API calls are going through the spring-gateway-service which integrated with spring security and keycloak.

Sample API : http:a*********.amazonaws.com/gateway-service/service-a/api/<endpoint>

enter image description here

I really appreciate if you can give help on this issue.

1

There are 1 best solutions below

3
On

The tokens in your Angular app are not shared between tabs, and this is expected: imagine if any other javascript code running in any other tab could access your tokens...

You could expect that the user session with current browser remains opened on Keycloak and that the authorization_code flow completes silently for the new tab (new tokens are delivered to the new public client instance without the need for the user to enter credentials).

You could investigate why this new tab doesn't bind to the existing session on Keycloak (or why this session has ended), but usage of public clients is discouraged by Spring Security team (and many others). Recommended alternative is to use a Backend For Frontend configured as an OAuth2 confidential client between Single Page Applications and resource servers.

I wrote a tutorial using spring-cloud-gateway with the TokenRelay filter to serve as BFF between an Angular app and a Spring resource server. The exact same pattern is applied in this project which I deploy on K8s. Keycloak is running in its own namespace (same cluster, but it would behave the same in a different one). You can try creating an account, logging in and opening a new tab, you'll be connected.