反向代理背后的 Keycloak 混合了内部和外部地址
Keycloak behind reverse proxy mixes internal and external addresses
我正在尝试使用 nginx 在反向代理后面设置一个 keycloak 实例,我几乎做到了。
我的(部分)docker-撰写:
version: '3.4'
services:
[...]
keycloak:
image: jboss/keycloak
environment:
- DB_VENDOR=[vendor]
- DB_USER=[user]
- DB_PASSWORD=[password]
- DB_ADDR=[dbaddr]
- DB_DATABASE=[dbname]
- KEYCLOAK_USER=[adminuser]
- KEYCLOAK_PASSWORD=[adminpassword]
- KEYCLOAK_IMPORT=/tmp/my-realm.json
- KEYCLOAK_FRONTEND_URL=https://auth.mydomain.blah/auth
- PROXY_ADDRESS_FORWARDING=true
- REDIRECT_SOCKET=proxy-https
[...]
我的 nginx conf 只是
server {
listen 443 ssl;
server_name auth.mydomain.blah;
ssl_certificate /etc/letsencrypt/live/auth.mydomain.blah/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.mydomain.blah/privkey.pem;
location / {
proxy_pass http://keycloak:8080;
}
}
它有效,我可以从 https://auth.mydomain.blah/auth
但是 访问 keycloak 当我查看 https://auth.mydomain.blah/auth/realms/campi/.well-known/openid-configuration
我得到这个:
{
"issuer": "https://auth.mydomain.blah/auth/realms/campi",
"authorization_endpoint": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/auth",
"token_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/token",
"introspection_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/userinfo",
"end_session_endpoint": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/logout",
"jwks_uri": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/certs",
"check_session_iframe": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/login-status-iframe.html",
[...]
为什么 keycloak 会混合内部和外部 uris?我错过了什么?
我们公司也有同样的“问题”。
通过 keycloak-admin.internaldomain.com 在内部访问它,但对于我们的普通用户,他们在外部访问 keycloak.externaldomain.com。
如果我在内部加载 .well-known/openid-configuration url 它有内部地址,但是使用外部加载它 url 它有那个。
除了偶尔向看到差异的工程师解释之外,它对我们没有造成任何问题。否则,没问题。
看来 keycloak 只使用它正在访问的任何域。
你的反向 proxy/nginx 没有正确转发主机头,所以 Keycloak 不知道请求使用了哪个 host/protocol 并且它使用 backend/internal 主机名。您需要设置几 proxy_set_header
行:
server {
listen 443 ssl;
server_name auth.mydomain.blah;
ssl_certificate /etc/letsencrypt/live/auth.mydomain.blah/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.mydomain.blah/privkey.pem;
location / {
proxy_pass http://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-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
我正在尝试使用 nginx 在反向代理后面设置一个 keycloak 实例,我几乎做到了。
我的(部分)docker-撰写:
version: '3.4'
services:
[...]
keycloak:
image: jboss/keycloak
environment:
- DB_VENDOR=[vendor]
- DB_USER=[user]
- DB_PASSWORD=[password]
- DB_ADDR=[dbaddr]
- DB_DATABASE=[dbname]
- KEYCLOAK_USER=[adminuser]
- KEYCLOAK_PASSWORD=[adminpassword]
- KEYCLOAK_IMPORT=/tmp/my-realm.json
- KEYCLOAK_FRONTEND_URL=https://auth.mydomain.blah/auth
- PROXY_ADDRESS_FORWARDING=true
- REDIRECT_SOCKET=proxy-https
[...]
我的 nginx conf 只是
server {
listen 443 ssl;
server_name auth.mydomain.blah;
ssl_certificate /etc/letsencrypt/live/auth.mydomain.blah/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.mydomain.blah/privkey.pem;
location / {
proxy_pass http://keycloak:8080;
}
}
它有效,我可以从 https://auth.mydomain.blah/auth
但是 访问 keycloak 当我查看 https://auth.mydomain.blah/auth/realms/campi/.well-known/openid-configuration
我得到这个:
{
"issuer": "https://auth.mydomain.blah/auth/realms/campi",
"authorization_endpoint": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/auth",
"token_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/token",
"introspection_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/userinfo",
"end_session_endpoint": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/logout",
"jwks_uri": "http://keycloak:8080/auth/realms/campi/protocol/openid-connect/certs",
"check_session_iframe": "https://auth.mydomain.blah/auth/realms/campi/protocol/openid-connect/login-status-iframe.html",
[...]
为什么 keycloak 会混合内部和外部 uris?我错过了什么?
我们公司也有同样的“问题”。
通过 keycloak-admin.internaldomain.com 在内部访问它,但对于我们的普通用户,他们在外部访问 keycloak.externaldomain.com。
如果我在内部加载 .well-known/openid-configuration url 它有内部地址,但是使用外部加载它 url 它有那个。
除了偶尔向看到差异的工程师解释之外,它对我们没有造成任何问题。否则,没问题。
看来 keycloak 只使用它正在访问的任何域。
你的反向 proxy/nginx 没有正确转发主机头,所以 Keycloak 不知道请求使用了哪个 host/protocol 并且它使用 backend/internal 主机名。您需要设置几 proxy_set_header
行:
server {
listen 443 ssl;
server_name auth.mydomain.blah;
ssl_certificate /etc/letsencrypt/live/auth.mydomain.blah/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.mydomain.blah/privkey.pem;
location / {
proxy_pass http://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-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
}
}