keycloak 的 Nginx 反向代理

Nginx reverse proxy for keycloak

我已经在 localhost:7070 部署了一个 keycloak 服务器(在 Docker 容器中,它在 运行 8080 上),现在我想为它设置一个反向代理。这是我的会议:[​​=19=]

server {
    listen       11080 ;

    location /auth/ {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Server $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-Host   $host;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass  http://localhost:7070/auth/;
    }
}

当我访问 http://my-ip:11080/auth 时,我可以看到欢迎页面。但是当我尝试按照欢迎页面上的 link 登录时,它显示错误并且 url 现在是 http://my-ip:auth/admin/,但我希望 http://my-ip:11080/auth/admin/ 端口为 11080

当我手动输入 http://my-ip:11080/auth/admin 并按 Enter 时,它会重定向到 http://my-ip/auth/admin/master/console/,但我希望 http://my-ip:11080/auth/admin/master/console/ 的端口为 11080

我也尝试了很多我找到的解决方案,但暂时没有成功。你能告诉我这里有什么问题吗?

更新: docker-compose.yml

version: "3.7"
services:
  keycloak:
    volumes:
      - keycloak-pgdb:/var/lib/postgresql/data
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "7070:8080"
    environment:
      - KEYCLOAK_USER=admin
      - KEYCLOAK_PASSWORD=password
      - DB_VENDOR=postgres
      - POSTGRES_PASSWORD=root
      - POSTGRES_DB=keycloak
      - DB_ADDR=localhost
      - DB_USER=postgres
      - DB_PASSWORD=root
      - PROXY_ADDRESS_FORWARDING=true
volumes:
  keycloak-pgdb:

Docker ps:

CONTAINER ID  IMAGE                   COMMAND           CREATED          STATUS          PORTS                               NAMES
30ad65460a0c  pic-keycloak_keycloak   "entrypoint.sh"   38 minutes ago   Up 38 minutes   5432/tcp, 0.0.0.0:7070->8080/tcp    pic-keycloak_keycloak_1

容器中的应用程序不知道您正在转发端口 11080,因此当应用程序呈现响应时,如果它遵循 X-Forwarded-xxxxx headers,它将使用 X-Forwarded-Poroto 来确定应该将重定向发送到哪里。

根据您的应用程序,您有 2 个选项可以处理这种情况:

  1. 识别 X-Forwarded-Port header 的应用程序可以被告知重定向到特定端口,如本例所示:
        proxy_set_header X-Forwarded-Port 11080
    
  2. 不遵守 header 中提供的规则的遗留应用程序可以通过响应重写传递来处理。这是 sub_filter 的示例:
    sub_filter     'http:/my-ip/auth'    'http:/my-ip:11080/auth';
    
    要使 sub_filter 正常工作,应安装并启用该模块 --with-http_sub_module