我正在尝试部署一个使用 Keycloak 作为身份验证服务和 GraphDB 作为存储库的应用程序。该应用程序在代理后面运行,我在 GraphDB 中设置 OpenID 配置时遇到问题。我创建了一个仅包含 Keycloak、GraphDB 和 nginx 代理的最小示例(
custom-nginx
仅包含带有服务反向代理声明的 nginx.conf
):
version: "3.9"
services:
nginx:
build:
context: nginx
image: custom-nginx
ports:
- 80:80
- 443:443
depends_on:
- auth-server
- db-server
auth-server-db:
image: postgres:13
environment:
POSTGRES_DB:
POSTGRES_USER:
POSTGRES_PASSWORD:
volumes:
- auth-server-db:/var/lib/postgresql/data
auth-server:
image: quay.io/keycloak/keycloak:22.0
command:
- start
environment:
KC_HOSTNAME_URL: ${URL}/auth
KC_HOSTNAME_ADMIN_URL: ${URL}/auth/
KC_HOSTNAME_STRICT_BACKCHANNEL: false
KC_PROXY: edge
KC_HTTP_ENABLED: true
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ${KC_ADMIN_PASS}
DB_VENDOR: POSTGRES
DB_ADDR: auth-server-db
DB_DATABASE: ${POSTGRES_DB}
DB_USER: ${POSTGRES_USER}
DB_SCHEMA: public
DB_PASSWORD: ${POSTGRES_PASSWORD}
ports:
- "127.0.0.1:8088:8080"
volumes:
- auth-server:/opt/keycloak/data
depends_on:
- auth-server-db
db-server:
image: ontotext/graphdb:10.3.2
depends_on:
- auth-server
environment:
GDB_JAVA_OPTS: -Dgraphdb.external-url=${URL}/db-server -Dgraphdb.auth.methods=openid -Dgraphdb.auth.openid.issuer=http://auth-server:8080/realms/termit -Dgraphdb.auth.openid.token_issuer=${URL}/auth/realms/termit -Dgraphdb.auth.openid.client_id=${GDB_CLIENTID} -Dgraphdb.auth.openid.username_claim=preferred_username -Dgraphdb.auth.openid.auth_flow=code -Dgraphdb.auth.openid.token_type=access -Dgraphdb.auth.openid.proxy=true -Ddefault.min.distinct.threshold=67108864 -Dgraphdb.workbench.cors.enable=true -Dgraphdb.workbench.cors.origin=* -Dgraphdb.workbench.cors.expose-headers=*
restart: always
ports:
- "127.0.0.1:7200:7200"
volumes:
- db-server:/opt/graphdb/home
volumes:
auth-server-db:
auth-server:
db-server:
当我尝试使用 GraphDB 进行此设置时,出现以下错误:
The Issuer "http://localhost/auth/realms/termit" provided in the configuration did not match the requested issuer "http://auth-server:8080/realms/termit"
。但如果我将颁发者 URI 设置为 localhost,它就无法连接到它。
我在代理后面基于 Spring 的应用程序的经验是,我会将 JWT 颁发者 URI 设置为身份验证服务器的公共 URL(例如,
http://localhost/auth/realms/termit
),并将 JWK 设置 URI 为内部 Docker 服务 URL。 GraphDB 中是否有类似的设置,以便我可以让这两个服务在代理后面工作(在 Docker 中)?
非常感谢任何帮助或示例。谢谢
nginx.conf
包含以下内容:
worker_processes 1;
events {
worker_connections 1024;
}
http {
client_max_body_size 25M;
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
add_header Access-Control-Allow-Origin *;
location /auth/ {
proxy_pass http://auth-server:8080/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Port $http_x_forwarded_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Increase buffer sizes to handle large headers sent by Keycloak and its clients
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
location = /db-server {
return 302 /db-server/;
}
location /db-server/ {
rewrite ^/graphdb/(.*) /$1 break;
proxy_pass http://db-server:7200;
proxy_redirect http://db-server:7200/ /db-server/;
proxy_set_header X-Forwarded-Host $host;
}
}
}
问题如果我理解得很好的话,Keycloak将使用它自己的url来发行令牌'localhost',使用代理的GraphDB将使用代理url'auth-server:8080'。
对于 GraphDB,请确保面向公众的 URL(颁发者)设置为 http://localhost/auth/realms/termit。 对于内部调用,GraphDB 需要使用内部 Docker 网络地址访问 Keycloak:http://auth-server:8080。但它应该根据面向公众的 URL 验证令牌。
另外,请确保 KC_HOSTNAME_URL 是您的公共 URL:http://localhost/auth。
评论后编辑:
仅支持关系型数据库https://www.keycloak.org/server/db
也许您可以尝试编写一个中间微服务,将其用作“自定义 Keycloak 提供程序”并自己建立链接。
回答我自己的问题: 我能够使配置工作,尽管不是我希望实现的方式。我的工作设置(最小示例可以在 GitHub 上找到并附有说明)将 GraphDB 配置为通过其公共 URL(例如,http://172.17.0.1/auth)而不是 Docker 服务 URL(http://172.17.0.1/auth
)访问 Keycloak /auth-服务器:8080).
在 Keycloak 方面,需要为客户端配置
public
访问权限,并确保访问令牌包含角色和受众声明。
对于本地测试,无法使用
http://localhost
作为公共 URL,因为服务将 URL 解释为服务容器内的 localhost ,而不是 Docker 主机(我的计算机)。相反,我使用了 http://172.17.0.1
,这是由 Docker 在主机系统上创建的 网络接口(IP 可能因系统而异)。