keycloak 无效参数:redirect_uri 在反向代理后面

keycloak Invalid parameter: redirect_uri behind a reverse proxy

在Keycloak前面如何正确配置NGINX作为代理?

以医生的身份询问和回答这个问题,因为我现在不得不反复这样做,过一会儿就忘记了细节。

这是专门处理 Keycloak 在反向代理后面的情况,例如nginx 和 NGINX 正在终止 SSL 并推送到 Keycloak。这与 keycloak Invalid parameter: redirect_uri 不同,尽管它会产生相同的错误消息。

这个的关键在文档中 https://www.keycloak.org/docs/latest/server_installation/index.html#identifying-client-ip-addresses

必须设置proxy-address-forwarding以及各种X-... headers.

如果您使用的是 https://hub.docker.com/r/jboss/keycloak/ 中的 Docker 图片,请设置环境。 arg -e PROXY_ADDRESS_FORWARDING=true.

server {
  server_name api.domain.com;

  location /auth {
    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_pass          http://localhost:8080;
    proxy_read_timeout  90;

 }

  location / {
    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_pass          http://localhost:8081;
    proxy_read_timeout  90;
  }



    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = api.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  server_name api.domain.com;
    listen 80;
    return 404; # managed by Certbot
}

如果您使用的是另一个代理,重要的部分是正在设置的 headers:

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;

Apache、ISTIO 和其他软件有自己的设置方法。

上面的答案涉及对代理所做的配置。

在 keycloak 容器的哪些方面,如果您在尝试登录管理控制台时遇到 redirect_uri 错误,则必须为 Keycloak 设置两个环境变量(从 10.0.0 版本开始)。 2) 在反向代理后面工作。

如果管理控制台的 URL 是 https://your.fqdn/auth 那么您必须设置:

KEYCLOAK_FRONTEND_URL = https://your.fqdn/auth

连同上述:

PROXY_ADDRESS_FORWARDING = true

下面是一个最小的 docker-compose.yml,它将在反向代理后面启动 keycloak 10,反向代理将请求转发到 https://your.fqdn docker主机端口8000,启动时在环境(或.env文件)中设置变量KEYCLOAK_ADMIN_PWDPG_KC_PASS即可,随心所欲。

version: '3'

volumes:
  pgkeycloak-data:
services:

  pg-keycloak:
    image: "postgres:12-alpine"
    container_name: pg-keycloak
    volumes:
      - "pgkeycloak-data:/var/lib/postgresql/data"
    restart: always
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloakdb
      POSTGRES_PASSWORD: ${PG_KC_PASS}

  auth:
    user: root
    privileged: true
    image: "quay.io/keycloak/keycloak:10.0.2"
    depends_on:
      - "pg-keycloak"
    restart: always
    ports:
      - 8000:443
    command:
      -Djboss.http.port=443
      -Djboss.bind.address=0.0.0.0
    environment:
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: ${KEYCLOAK_ADMIN_PWD}
      KEYCLOAK_FRONTEND_URL: https://your.fqdn/auth
      PROXY_ADDRESS_FORWARDING: "true"
      DB_USER: keycloakdb
      DB_PASSWORD: ${PG_KC_PASS}
      DB_ADDR: pg-keycloak
      DB_VENDOR: postgres

我遇到了同样的问题,因为我 reused/copy-pasted 来自另一个服务的代理配置。

一旦我将 proxy_set_header Host $host:$server_port; 更改为 proxy_set_header Host $host;,它就起作用了。

(移除:$server_port)