Confirm the Keycloak token by checking it against two separate URLs

In my system, I have a setup based on Docker compose with back-end and front-end components. The back-end is developed using Python Flask and runs in multiple docker containers, while the front-end is coded in TypeScript with Angular. Communication between the front-end and back-end is established through Restful APIs, and Nginx acts as a proxy. However, there is an issue with Keycloak token verification between the front-end and back-end.

Configuration of KeyCloak (and MySQL) in the 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

Nginx configuration related to the issue:

    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 am utilizing the above /api/auth/verify URL for authentication purposes in all endpoints. For example:

    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 configurations for TypeScript/Angular:

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

app-init.ts content:

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);
}

The app.module.ts file includes the following section:

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

An error message that I encountered:

https://i.sstatic.net/Cw1d4.png

Apeek into the frontend client's configuration in Keycloak:

https://i.sstatic.net/Nk7RY.png

The issues summed up:

  • The Nginx uses the http://keycloak:8080 URL which works within the Docker network but not with localhost.
  • The front-end (TS/Angular) uses http://localhost:8080 URL which may cause compatibility problems with the Nginx configuration.
  • When a request is made from the front-end to authenticate via the API using Nginx, an "Invalid Token" error occurs.
  • Based on my research, this error seems to stem from using tokens generated at http://localhost:8080 to authenticate at http://keycloak:8080.

Summary of URLs utilized:

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

The question at hand:

  • How can I resolve the aforementioned issue? Any suggestions would be greatly appreciated.

1st EDIT:

Although I attempted setting the front-end URL to http://localhost:8080 and http://localhost:4200, both resulted in the below issue:

https://i.sstatic.net/kEjO1.png

Answer №1

Eureka! I've cracked the code!

The Frontend URL parameter in Keycloak's general configuration can be quite deceptive. Even though my front-end is hosted on a URL like http://localhost:4200, it simply wouldn't work when specified as the front-end URL parameter in Keycloak (I tried repeatedly).

In my question, you'll notice that for the keycloak-angular module configuration, the Keycloak URL is defined as

url: 'http://localhost:8080/auth/'
. Surprisingly, setting this URL as the Frontend URL parameter in Keycloak's general configuration (or as an input parameter in the docker-compose.yml file) made everything run smoothly.

https://i.sstatic.net/Uyeow.png

Important Note:

  • Simply using the base URL (http://localhost:8080) was not sufficient; the /auth suffix was also necessary for it to function correctly (The complete working URL is: http://localhost:8080/auth/).

Answer №2

Apologies for the delay,

Have you experimented with adding 127.0.0.1 keycloak to your hosts file and substituting http://localhost:8080/auth/ with http://keycloak:8080/auth/ in your Keycloak configuration for TypeScript/Angular.

Hosts File Location:

In Linux/Unix, it can be found at: /etc/hosts. In Windows, look for it in

c:\Windows\System32\Drivers\etc\hosts
.

Explanation:

  1. Nginx connects to the http://keycloak:8080 URL within the docker network.

  2. The front-end (TS/Angular) also references http://keycloak:8080.

  3. This setup should prevent invalid token errors since both token acquisition and verification occur on the same URL - http://keycloak:8080.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The cloud build process concludes with a FAILURE status, leading to a cascade of additional issues

Recently, I was engrossed in a tutorial from the Google Tech Build YouTube channel titled "Serverless Expeditions." It's part of their new series and I must say, it's truly impressive. I highly recommend checking it out. Although I was new to ex ...

What is the process for uploading an image with express-fileupload?

Looking to upload an image to Cloudinary via Postman using the express-fileupload library for handling multipart forms. Here is a snippet from my index.ts file: import fileUpload from "express-fileupload"; app.use(fileUpload()); In my controller ...

The error message "Property '$store' is not defined on type 'ComponentPublicInstance' when using Vuex 4 with TypeScript" indicates that the property '$store' is not recognized

I'm currently working on a project that involves using TypeScript and Vue with Vuex. I've encountered an error in VSCode that says: Property '$store' does not exist on type 'ComponentPublicInstance<{}, {}, {}, { errors(): any; } ...

The challenge of generics in Typescript: destructuring and spreading

I am facing an issue with destructing parameters and creating a new object of the same type in Typescript. The following code functions properly: function customFunc<T extends { attribute: string }>(parameter: T): T { const { ...rest } = paramete ...

Is your Angular 2 routing failing to work properly after a page refresh or reload when using gulp?

I've recently started learning Angular 2, and I encountered an issue with routing. During the development phase, I ran my application using npm start. However, after migrating to gulp.js, when I run the application by typing gulp, everything works fin ...

Is it possible to constrain generic indexed access parameters?

Consider the following scenario: type Group = | { type: "string"; payload: string; } | { type: "number"; payload: number; }; A function can be created as shown below: const groupFunction = <T exte ...

What methods can be implemented to ensure ComponentOverride's universality?

These type definitions for markdown-to-jsx don't seem to be generic enough, causing issues like the one mentioned below. For more details, refer to Why is type SFC<AnchorProps> not assignable to type SFC<{}>? /Users/sunknudsen/Sites/sunk ...

Is there a way to navigate to a specific component selector within an ngFor loop?

I have a scenario where I have multiple components running inside *ngFor on the same page. My goal is to create button links at the top of the page that, when clicked, will scroll to the corresponding component on the page. Below are the code snippets tha ...

Tips for properly formatting a fixed table header

I'm currently facing an issue with the sticky header style in my data table. I have created a simple Angular component along with a specific directive: sticky.directive.ts @Directive({ selector: '[sticky]' }) export class StickyDirecti ...

The error message "element is not defined" is indicating an issue related to the cordova-plugin-google

In my current project using Ionic 3, I decided to implement map-related features by incorporating the Google Maps plugin recommended by the Ionic Team. This specific plugin serves as a wrapper around cordova-plugin-googlemaps. Following the steps outlined ...

Components that rely on Angular's properties

I currently have three main components in my project: CategoryComponent - responsible for displaying a list of categories ListComponent - displays elements based on the selected category ScreenComponent - combines MenuComponent and ContentComponent toget ...

Ensuring Mongoose Schema complies with an external API

My database schema includes a mongoose User schema with the following structure: const User: Schema = new Schema({ // some other fields email: {type: String, unique: true, require: true, validate: [myValidator, 'invalid email provided'], // some ...

Angular2: Observable flatMap issue with Undefined Property Subscribe

I am using the final version of Angular 2 and attempting to make an HTTP request that relies on another HTTP request. In my scenario, I am trying to retrieve an account with the user ID as a parameter which is obtained from another HTTP request (getUser). ...

Troubleshooting the Angular 7 mat-select issue caused by the "ellipsis" CSS property with three dots

I am facing an issue with a mat-select property called "ellipsis". The three points appear in a different color than the text itself. I attempted to change it to white using the following code, but the dots still remain black. ::ngdeep .example{ ...

Struggling to combine interface with import and local variables - any solutions?

Although examples have demonstrated the merging of interfaces in a single file, I am facing challenges when trying to merge interfaces that are located in different files. I want to clarify that I am not extending any modules, just interfaces. /types/ind ...

What is the recommended TypeScript type to be returned from a GraphQL resolver when using ESLint?

Repository Link https://github.com/inspiraller/apollo-typescript The code is functioning correctly, however, Eslint typescript is raising complaints. An eslint error occurs on the following code block: Query: { players: () => players } Miss ...

Dealing with Overwhelmingly Large Angular 5 Components

I'm currently developing a project in Angular 5 and one of our component files is becoming quite large, reaching nearly a thousand lines and continuing to grow. This will eventually make it difficult to manage and understand. We are seeking advice on ...

Attempting to successfully upload this Angular 7 form to my TypeScript code. Making use of ngForm and [(ngModel)] to achieve this

I am having trouble passing form information using the onSubmit() function. It seems to be undefined when I try to execute it initially. Could there be a syntax error that I'm missing? <form class="gf-formbox" name="credentials" (ngSubmit)="onSubm ...

Help! My Angular CLI version 8.2.2 is displaying squares instead of the Font-awesome icons

I successfully added Font Awesome using the command npm install --save font-awesome angular-font-awesome from https://www.npmjs.com/package/angular-font-awesome. After linking it in my angular.json file: "styles": [ "src/styles.css", "node_modu ...

Warning: Potential spacing issues when dynamically adjusting Material UI Grid using Typescript

When working with Typescript, I encountered an error related to spacing values: TS2322: Type 'number' is not assignable to type 'boolean | 7 | 2 | 10 | 1 | 3 | 4 | 5 | 6 | 8 | "auto" | 9 | 11 | 12'. No lint errors found Version: typesc ...