验证来自两个不同 URL 的 Keycloak 令牌

mil*_*azs 6 nginx typescript docker keycloak angular

我有一个Docker compose带有后端和前端组件的基础系统。后端是Python Flask用几个 docker 容器编写并运行的,前端是TypeScriptAngular. 前端通过Restful API与后端进行通信。代理是使用创建的Nginx。但Keycloak前端和后端之间不能进行Token验证。

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

  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
Run Code Online (Sandbox Code Playgroud)

相关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;
    }
Run Code Online (Sandbox Code Playgroud)

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

    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;
    }
Run Code Online (Sandbox Code Playgroud)

我的/Keycloak的配置:TypeScriptAngular

export const environment = {
  production: false,
  keycloakConfig: {
    url: 'http://localhost:8080/auth/',
    realm: 'master',
    clientId: 'frontend'
  }
};
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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

  providers: [
    KeycloakService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializer,
      multi: true,
      deps: [KeycloakService]
    }
  ]
Run Code Online (Sandbox Code Playgroud)

获取错误:

出现错误

frontend客户端配置Keycloak

钥匙斗篷配置

我的问题点:

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

总结一下我用过的网址:

  • API 的网址:http://localhost
  • Docker 内的 Keycloak URL:http://keycloak:8080
  • 前端的钥匙斗篷:http://localhost:8080
  • 前端的 URL :http://localhost:4200

我的问题:

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

1.编辑:

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

前端URL问题

mil*_*azs 6

我刚刚找到了解决方案!

Frontend URL参数在一般配置中是一个相当具有误导性的参数Keycloak。我的前端位于http://localhost:4200URL 上,但正如我在问题中提到的,URL 不能作为 Keycloak 中的前端 URL 参数(我已经测试过很多次)。

keycloak-angular正如您在我的问题中看到的,在模块配置中,KeycloakURL 设置为url: 'http://localhost:8080/auth/'。如果我将该 URL 设置为常规配置Frontend URL中的参数Keycloak(或docker-compose.yml文件中的输入参数),我的系统将发挥作用。

前端配置

笔记:

  • 基本 URL ( http://localhost:8080) 不够,因此/auth还需要后缀(有效的完整 URL:http://localhost:8080/auth/)。