从两个不同的 URL 验证 Keycloak 令牌 [英] Verify Keycloak token from two different URLs

查看:40
本文介绍了从两个不同的 URL 验证 Keycloak 令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于 Docker compose 的系统,带有后端和前端组件.后端使用 Python Flask 编写并在多个 docker 容器中运行,前端使用 TypeScriptAngular 编写.前端通过 Restful API 与后端通信.代理是使用 Nginx 创建的.但是Keycloak令牌验证在前端和后端之间不起作用.

我的KeyCloak(和MySQL)部分docker-compose.yml 文件:

 mysql:图像:mysql:5.7.31端口:- 9988:3306卷:- keycloak_data:/var/lib/mysql环境:MYSQL_ROOT_PASSWORD:rootMYSQL_DATABASE:钥匙斗篷MYSQL_USER:钥匙斗篷MYSQL_PASSWORD:密码网络:- auth_net钥匙斗篷:图片:jboss/keycloak:13.0.1环境:DB_VENDOR:MYSQLDB_ADDR: mysqlDB_DATABASE:密钥斗篷DB_USER:钥匙斗篷DB_PASSWORD:密码KEYCLOAK_USER:管理员KEYCLOAK_PASSWORD:管理员PROXY_ADDRESS_FORWARDING:真";端口:- 8080:8080- 8443:8443取决于:- mysql网络:- auth_net

相关Nginx配置部分:

 location/api/auth/verify {内部的;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;}

我对每个端点使用上述 /api/auth/verify URL 作为验证.例如:

 位置/api/users {auth_request/api/auth/verify;重写 ^/api/(.*)/$1 中断;proxy_pass http://users:6000;proxy_pass_request_headers 开启;proxy_set_header 主机 $host;proxy_set_header X-Real-IP $remote_addr;}

我的 Keycloak TypeScript/Angular 配置:

export const environment = {生产:假,密钥斗篷配置:{url: 'http://localhost:8080/auth/',领域:'主人',客户 ID:'前端'}};

app-init.ts:

import { KeycloakService, KeycloakOptions } from 'keycloak-angular';从'src/environments/environment'导入{环境};导出函数初始值设定项(keycloak:KeycloakService):()=>承诺<任何>{const 选项:KeycloakOptions = {配置:environment.keycloakConfig};return(): Promise

Keycloakfrontend客户端的配置:

我的问题:

  • Nginx 使用 http://keycloak:8080 URL,它是 docker 系统内部的网络(Nginx 没有查看 Docker 中的 localhost).
  • 前端 (TS/Angular) 使用从外部可见的 http://localhost:8080 URL(从用户的浏览器)(理论上前端不会从用户的浏览器看到 keycloak 网络)
  • 当我从调用我的 API 的前端发送请求(想要根据上述 Nginx 示例验证令牌)时,我收到 Invalid Token 错误
  • 根据我的调查,我收到此错误是因为我在 http://localhost:8080 URL 上获得了令牌,并且我想在 http://keycloak 上验证它:8080 网址.

我使用过的网址汇总:

  • API 的 URL:http://localhost
  • Docker 中的 Keycloak URL:http://keycloak:8080
  • 前端的Keycloak:http://localhost:8080
  • Fornt-end 的 URL : http://localhost:4200

我的问题:

  • 如何解决上述问题?我对想法非常开放.

1.

如果我尝试将前端 URL 设置为 http://localhost:8080http://localhost:4200 但我得到以下两种情况下的问题:

解决方案

我刚刚找到了解决方案!

Frontend URL 参数在 Keycloak 常规配置中是一个相当误导的参数.我的前端在 http://localhost:4200 URL 上,但正如我在问题中提到的,URL 不能作为 Keycloak 中的前端 URL 参数(我已经测试了很多次).

正如您在 keycloak-angular 模块配置中的问题中所见,Keycloak URL 设置为 url: 'http://localhost:8080/auth/'.如果我将该 URL 设置为 Keycloak 常规配置中的 Frontend URL 参数(或作为 docker-compose.yml 文件中的输入参数)我的系统很有魅力.

注意:

  • 基本 URL (http://localhost:8080) 是不够的,所以还需要 /auth 后缀(有效的完整 URL:http://localhost:8080/auth/).

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:

Config of frontend client in Keycloak:

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:

解决方案

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.

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/).

这篇关于从两个不同的 URL 验证 Keycloak 令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆