You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

容器化环境下基于NGINX反向代理配置Kong与Keycloak:端口隐藏问题解决方案咨询

解决Kong + Keycloak + NGINX重定向暴露端口的问题

嘿,这个问题我之前帮不少人解决过——核心原因就是你的Kong和Keycloak不知道外部用户是通过NGINX的域名/端口访问的,所以它们生成重定向URL的时候直接用了容器内部的8000、8080端口。下面给你一步步拆解正确的配置方式:

一、先搞定NGINX:传递真实请求信息给后端

NGINX作为反向代理,必须把外部访问的域名、协议、端口这些关键信息传递给Kong和Keycloak,这样后端服务才能生成正确的外部URL。给你一个示例配置:

server {
    listen 80;
    server_name your-domain.com; # 替换成你的实际外部域名

    # 转发请求到Kong的配置
    location /api/ {
        proxy_pass http://kong:8000/; # kong是容器服务名,对应内部8000端口
        # 传递真实请求头,让Kong知道外部访问的细节
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme; # 告诉Kong外部用的是http/https
        proxy_set_header X-Forwarded-Port $server_port; # 传递外部访问的端口
    }

    # 转发请求到Keycloak的配置(如果外部访问Keycloak也走NGINX)
    location /auth/ {
        proxy_pass http://keycloak:8080/; # keycloak是容器服务名,对应内部8080端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
        # Keycloak专属:处理路径前缀,避免生成错误的URL路径
        proxy_set_header X-Forwarded-Context /auth;
    }
}

二、配置Kong:指定外部访问地址

Kong需要明确知道用户从外部访问它的基础URL,这样OIDC插件生成的重定向回调地址才会正确。有两种配置方式:

方式1:容器启动时通过环境变量设置

在你的docker-compose.yml里给Kong添加环境变量:

services:
  kong:
    image: kong:latest
    environment:
      - KONG_PROXY_ACCESS_LOG=/dev/stdout
      - KONG_ADMIN_ACCESS_LOG=/dev/stdout
      - KONG_PROXY_ERROR_LOG=/dev/stderr
      - KONG_ADMIN_ERROR_LOG=/dev/stderr
      - KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl
      # 关键配置:外部用户访问Kong的完整地址
      - KONG_PROXY_URL=http://your-domain.com/api/

方式2:通过Kong Admin API动态更新

如果Kong已经在运行,直接调用Admin API修改配置:

curl -X PATCH http://kong:8001/settings \
  --data "proxy_url=http://your-domain.com/api/"

三、配置Keycloak:设置前端访问URL

Keycloak必须配置前端URL,否则它会默认用内部8080端口生成登录、重定向地址。同样有两种方式:

方式1:容器启动时通过环境变量设置

在docker-compose.yml里给Keycloak添加环境变量:

services:
  keycloak:
    image: quay.io/keycloak/keycloak:latest
    environment:
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=your-admin-pass
      - KC_PROXY=edge # 告诉Keycloak它运行在反向代理后面
      - KC_HOSTNAME=your-domain.com # 外部域名
      - KC_HOSTNAME_PATH=/auth # 对应NGINX里的/auth路径
      - KC_HOSTNAME_PORT=80 # 外部端口(如果用HTTPS就是443)
    command: start

方式2:通过Keycloak控制台设置

  1. 通过NGINX访问Keycloak Admin控制台:http://your-domain.com/auth/admin
  2. 进入目标Realm的Realm Settings -> General
  3. 找到Frontend URL,设置为http://your-domain.com/auth/
  4. 点击保存生效

四、调整Kong OIDC插件:用正确的回调地址

最后,确保OIDC插件的配置里,redirect_uridiscovery地址都用外部URL,而不是内部容器地址:

curl -X POST http://kong:8001/services/your-target-service/plugins \
  --data "name=oidc" \
  --data "config.client_id=your-kong-oidc-client" \
  --data "config.client_secret=your-client-secret" \
  --data "config.discovery=http://your-domain.com/auth/realms/your-realm/.well-known/openid-configuration" \
  --data "config.redirect_uri=http://your-domain.com/api/your-protected-route/callback"

验证步骤

  1. 重启所有容器,确保配置都生效
  2. 访问受保护的API路径:http://your-domain.com/api/your-protected-route
  3. 检查重定向到Keycloak的URL,应该是http://your-domain.com/auth/...(没有8080端口)
  4. 登录成功后,重定向回Kong的URL应该是http://your-domain.com/api/.../callback(没有8000端口)

如果还是有问题,可以排查这几点:

  • NGINX的proxy_set_header是否完整传递了所有头信息
  • Kong的proxy_url是否和外部访问路径完全匹配
  • Keycloak的KC_PROXY=edge是否配置,Frontend URL是否正确
  • OIDC插件的redirect_uri是否和外部访问路径一致

内容的提问来源于stack exchange,提问作者SoupriceCoder

火山引擎 最新活动