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_PWD
和PG_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)
在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_PWD
和PG_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)