I have an application using Angular, Keycloak, and Nginx. Nginx is configured to handle reverse proxy and SSL termination. The application worked fine before enabling SSL termination. After enabling it, I encounter the following issue: I visit the application, and it redirects me to the Keycloak login page. I enter my credentials, and the application redirects me to the homepage (works fine up to this point). If I reload the page or navigate to another page, the application enters a loop. The console log shows repeated requests to: https://domain/realms/realm/protocol/openid-connect/3p-cookies/step1.html https://domain/realms/realm/protocol/openid-connect/3p-cookies/step2.html Additionally: If I refresh the page before logging in, the same loop occurs. In the network tab, I observe that a request to https://domain/realms/realm/protocol/openid-connect/auth?client_id returns a 200 response (HTML file) instead of the expected 302 redirect. This is followed by step1 and step2 requests. Cookies AUTH_SESSION_ID, KEYCLOAK_SESSION, KEYCLOAK_IDENTITY, and their legacy versions are saved in the browser. Technical Details: Angular: 18 Keycloak Angular: ^16.1.0 Keycloak JS: ^25.0.6 Keycloak Docker Version: quay.io/keycloak/keycloak:25.0.6 Relevant Code: Angular Configuration (app.module.ts): export function initializeKeycloak(keycloak: KeycloakService) { return () => keycloak.init({ config: { url: 'https://domain', realm: 'realm', clientId: 'realm-client', }, initOptions: { onLoad: 'check-sso', silentCheckSsoRedirectUri: window.location.origin + '/assets/silent-check-sso.html', checkLoginIframe: false, }, enableBearerInterceptor: true, bearerExcludedUrls: ['/assets', '/clients/public'], }); } Authguard import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, } from '@angular/router'; import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular'; @Injectable({ providedIn: 'root', }) export class AuthGuard extends KeycloakAuthGuard { constructor( protected override readonly router: Router, protected readonly keycloak: KeycloakService ) { super(router, keycloak); } public async isAccessAllowed( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ) { // Force the user to log in if currently unauthenticated. if (!this.authenticated) { console.log("authguard: not auth"); await this.keycloak.login({ redirectUri: window.location.origin + state.url }); } // Get the roles required from the route. const requiredRoles = route.data['roles']; console.log("authguard: auth 1"); // Allow the user to to proceed if no additional roles are required to access the route. if (!(requiredRoles instanceof Array) || requiredRoles.length === 0) { return true; } // Allow the user to proceed if all the required roles are present. console.log("authguard: auth 2"); return requiredRoles.every((role) => this.roles.includes(role)); } } Nginx Configuration: events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 443 ssl; server_name domain; # SSL certificates ssl_certificate /etc/pki/tls/domain.crt; ssl_certificate_key /etc/pki/tls/domain.rsa; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; root /var/www/html/dist; index index.html; # Frontend Configuration location / { try_files $uri /index.html; } # Backend API Proxy location /api/ { proxy_pass ip; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Authorization $http_authorization; } #Keycloak Proxy location /realms/ { proxy_pass http://ip; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_pass_header Set-Cookie; } #Keycloak Proxy location /resources/ { proxy_pass http://ip; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Proto $scheme; } } } Keycloak Docker Configuration: services: keycloak: image: quay.io/keycloak/keycloak:25.0.6 container_name: keycloak environment: KEYCLOAK_IMPORT: /opt/keycloak/data/import/realm.json KC_HTTP_ENABLED: 'true' KC_HTTP_PORT: 8081 KC_PROXY_HEADERS: xforwarded PROXY_ADDRESS_FORWARDING: 'true' KC_HOSTNAME_STRICT: 'false' Question: What could be causing this redirect loop after enabling SSL termination? How can I resolve it while maintaining secure SSL termination? Continue reading...