从两个不同的 URL 验证 Keycloak 令牌

Verify Keycloak token from two different URLs

我有一个基于 Docker compose 的系统,包含后端和前端组件。后端用 Python Flask 和 运行 写在几个 docker 容器中,前端用 TypeScriptAngular 写。前端通过RestfulAPIs与后端通信。代理是使用 Nginx 创建的。但是Keycloak Token验证在前后端之间不起作用

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

  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配置部分:

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

我对每个端点都使用上面的 /api/auth/verify URL 作为验证。例如:

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

我的 Keycloak 配置 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);
}

我的 app.module.ts 文件包含以下部分:

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

获取错误:

Keycloakfrontend 客户端的配置:

我的问题点数:

总结一下我用过的URLs:

我的问题:

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

我来晚了,

但是您是否尝试过在主机文件中添加 127.0.0.1 keycloak 并在 TypeScript/Angular.

的 Keycloak 配置中将 http://localhost:8080/auth/ 替换为 http://keycloak:8080/auth/

主机文件位置:

在Linux/Unix中,它的位置是:/etc/hosts 在windows中,它的位置在c:\Windows\System32\Drivers\etc\hosts.

解释:

  1. Nginx使用的是http://keycloak:8080URL,这是docker系统内部的网络。

  2. 前端(TS/Angular)使用http://keycloak:8080

  3. 您不会收到无效令牌错误,因为您是从 http://keycloak:8080 获取令牌并使用相同的 URL.[=16= 进行验证]