skip to Main Content

I have a Docker compose based system with back-end and front-end components. The back-end is written in Python Flask and run in several docker containers and front-end is written in TypeScript with Angular. The front-end communicates with back-end via Restful APIs. The proxy is created with Nginx. But the Keycloak Token verification doesn’t work between front-end and back-end.

My KeyCloak (and MySQL) section of docker-compose.yml file:

  mysql:
    image: mysql:5.7.31
    ports:
      - 9988:3306
    volumes:
      - keycloak_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: keycloak
      MYSQL_USER: keycloak
      MYSQL_PASSWORD: password
    networks:
      - auth_net

  keycloak:
    image: jboss/keycloak:13.0.1
    environment:
      DB_VENDOR: MYSQL
      DB_ADDR: mysql
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_PASSWORD: password
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: admin
      PROXY_ADDRESS_FORWARDING: "true"
    ports:
      - 8080:8080
      - 8443:8443
    depends_on:
      - mysql
    networks:
      - auth_net

Related Nginx config part:

    location /api/auth/verify {
        internal;
        proxy_method POST;
        proxy_intercept_errors on;
        proxy_pass http://keycloak:8080/auth/realms/master/protocol/openid-connect/userinfo;
        error_page 400 =401 /401.html;
    }

I use the above /api/auth/verify URL for every endpoints as verification. Eg.:

    location /api/users {
        auth_request /api/auth/verify;
        rewrite ^/api/(.*) /$1  break;
        proxy_pass http://users:6000;
        proxy_pass_request_headers on;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

My Keycloak config for TypeScript/Angular:

export const environment = {
  production: false,
  keycloakConfig: {
    url: 'http://localhost:8080/auth/',
    realm: 'master',
    clientId: 'frontend'
  }
};

app-init.ts:

import { KeycloakService, KeycloakOptions } from 'keycloak-angular';
import { environment } from 'src/environments/environment';

export function initializer(keycloak: KeycloakService): () => Promise<any> {
  const options: KeycloakOptions = {
    config: environment.keycloakConfig
  };

  return (): Promise<any> => keycloak.init(options);
}

My app.module.ts file contains the following section:

  providers: [
    KeycloakService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializer,
      multi: true,
      deps: [KeycloakService]
    }
  ]

The getting error:

Getting error

Config of frontend client in Keycloak:

Keycloak config

My problem in points:

  • The Nginx uses the http://keycloak:8080 URL which is the network inside the docker system (The Nginx doesn’t see the localhost from Docker).
  • The front-end (TS/Angular) uses the http://localhost:8080 URL which is visible from outside (from the users’ browser) (In theory the front-end doesn’t see the keycloak network from user’s browser)
  • When I send a request from front-end which calls my API (which want to verify the token based on above Nginx example), I get Invalid Token error
  • Based on my investigation I get this error because I get the token on http://localhost:8080 URL and I want to verify it on http://keycloak:8080 URL.

Summarize of my used URLs:

  • API’s URL: http://localhost
  • Keycloak URL inside Docker: http://keycloak:8080
  • Keycloak on front-end side: http://localhost:8080
  • Fornt-end’s URL : http://localhost:4200

My question:

  • How can I solve the above problem? I am very open for ideas.

1. EDIT:

If I have tried to set the front-end URL to http://localhost:8080, and http://localhost:4200 but I got the below issue in both cases:

front-end URL issue

2

Answers


  1. Chosen as BEST ANSWER

    I have just found the solution!

    The Frontend URL parameter is a quite misleading in the Keycloak general configuration. My front-end is on http://localhost:4200 URL but as I mentioned in my question that URL wasn't working as front-end URL parameter in Keycloak (I have tested is many times).

    As you can see in my question in the configuration of keycloak-angular module the Keycloak URL is set as url: 'http://localhost:8080/auth/'. If I set that URL as Frontend URL parameter in the Keycloak general configuration (or as input parameter in docker-compose.yml file) my system works as charm.

    Front-end config

    Note:

    • The base URL (http://localhost:8080) is not enough so the /auth suffix is also needed (The full URL which is working: http://localhost:8080/auth/).

  2. I am bit late,

    but have you tried to add 127.0.0.1 keycloak in your hosts file and replace http://localhost:8080/auth/ with http://keycloak:8080/auth/ in your Keycloak config for TypeScript/Angular.

    Hosts File Location:

    In Linux/Unix, its location is at: /etc/hosts
    In windows, its location is at c:WindowsSystem32Driversetchosts.

    Explanation:

    1. The Nginx uses the http://keycloak:8080 URL which is the network inside the docker system.

    2. The front-end (TS/Angular) uses the http://keycloak:8080

    3. You will not get the invalid token error, as you are getting the token from http://keycloak:8080 and as well verifying with the same URL.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search