如果每次访问 Neo4j Browser 都要求输入一遍图数据库账号,团队规模超过十人后就会明显拖慢数据查询流程,尤其在企业已经使用 Keycloak、Azure AD 或 Okta 统一管理身份的情况下。Neo4j 企业版提供 OIDC 单点登录能力,认证过程被转移到外部身份提供商,用户只需在身份源完成登录,浏览器与 Bloom 会自动通过回调地址换取令牌并进入图数据库界面。下面先梳理实现方式与关键前提。

一、Neo4j 单点登录的两种实现路径
第一种路径是使用 Neo4j 企业版内置的 OIDC 认证提供程序。它的核心是在 neo4j.conf 中把 dbms.security.authentication_providers 设置为 oidc,此时 Neo4j 自己会作为 OpenID Connect 的依赖方,向身份提供商发起授权请求、处理回调并校验 ID Token。用户登录成功后,Neo4j 会为浏览器会话建立单点登录状态。优点是链路短、不需要额外部署代理组件;缺点是该能力主要服务于 Neo4j Browser 和 Bloom 这类 HTTP 入口,驱动程序直接访问 Bolt 时仍然需要单独携带令牌或使用基础认证。
第二种路径是在 Neo4j 前面增加一层 Nginx 与 oauth2-proxy。无论使用社区版还是企业版,都可以用 oauth2-proxy 保护 Neo4j 的 7474 端口,未登录用户被重定向到身份提供商,登录成功后再由 Nginx 把请求转发给 Neo4j。这种方式的好处是不依赖 Neo4j 自身的 OIDC 实现,适合老版本或社区版;但它的保护范围主要是 HTTP 入口,对于 7687 Bolt 端口的统一认证比较麻烦。实际项目中,如果企业已经拥有成熟的网关和 oauth2-proxy 体系,可以快速接入;如果正在使用企业版,通常优先考虑内置 OIDC。
两种方案并不完全互斥。部分团队会用 oauth2-proxy 保护公共的浏览器入口,同时在企业内部驱动连接层继续使用服务账号和最小权限策略。本文后半部分会同时给出 Keycloak 身份源配置、Neo4j 内置 OIDC 配置和 Nginx 兜底配置,方便按版本和场景选择。
二、Keycloak 身份源侧配置
无论选择哪条路径,身份提供商都需要知道 Neo4j 这个客户端的存在。以 Keycloak 为例,首先创建一个独立 Realm,例如 graphdb,再在该 Realm 下创建 Client,Client ID 可以命名为 neo4j-browser。客户端协议使用 openid-connect,访问类型建议选择 public,这样浏览器端可以使用 PKCE 流程,不需要在 Neo4j 或 oauth2-proxy 的配置文件中保存客户端密钥。
接着需要配置有效的重定向 URI。对于 Neo4j 内置 OIDC,回调地址通常就是 Neo4j Browser 的入口地址;如果设置了 Nginx 反向代理,应该填写外部访问地址。Keycloak 只允许用户登录后跳回这里,因此地址必须与 Neo4j 或 oauth2-proxy 发起认证时使用的回调完全一致,否则会遇到回调不匹配错误。
最后还要添加映射器,把用户属性放进 Token。至少需要把用户名映射到 ID Token 的 preferred_username 或 email 声明,同时可以把 Keycloak 的组信息映射到 groups 声明。Neo4j 在登录后会从这些声明里取出用户名和角色,如果这里缺少映射,登录成功也可能出现用户无法映射到图数据库角色的情况。
三、Neo4j 内置 OIDC 核心配置
企业版配置 OIDC 的关键是修改 neo4j.conf。下面给出一个基于 Keycloak 的示例,其中身份源地址使用 idp.ipipp.com 作为占位域名,实际部署时需要替换成真实 Keycloak 或 Azure AD 地址。
dbms.security.authentication_providers=oidc,native dbms.security.oidc.issuer=https://idp.ipipp.com/realms/graphdb dbms.security.oidc.client_id=neo4j-browser dbms.security.oidc.auth_flow=pkce dbms.security.oidc.claims.username=preferred_username dbms.security.oidc.claims.groups=groups
issuer 参数对应 Keycloak 中 Realm 的地址,Neo4j 会自动在这个地址后面追加 /.well-known/openid-configuration 来发现授权端点、令牌端点和 JWKS 地址,因此这里不需要手动写全路径。如果 Keycloak 客户端被配置为 confidential 类型,可以额外增加 dbms.security.oidc.client_secret;使用 public 加 PKCE 时则可以省略。保留 native 提供程序是为了在 OIDC 配置错误时仍然能够通过本地管理员账号登录排查,避免把自己锁在数据库外面。
配置完成后重启 Neo4j,打开 Browser 时应当会直接跳转到 Keycloak 登录页面。登录成功后回到 Neo4j,可以看到当前用户已经切换为 OIDC 映射过来的用户名。如果仍然显示 neo4j 本地用户,说明 OIDC 会话没有建立,需要检查回调地址、Token 中的用户名声明以及浏览器网络请求。
角色控制方面,Neo4j 需要把 OIDC 返回的 groups 声明映射到内部角色。不同版本的参数略有差异,通常需要查看当前企业版文档确认角色映射写法。配置后可以用一个只拥有 reader 角色的测试用户访问,判断是否只能执行只读查询,从而验证角色映射是否真正生效。
四、Nginx 与 oauth2-proxy 兜底方案
如果使用的是 Neo4j 社区版,或者暂时不想直接改动数据库认证配置,可以在前面加一层 oauth2-proxy。oauth2-proxy 本身负责和 Keycloak、Azure AD 等身份源交互,登录成功后向浏览器写入 Cookie,后续请求携带该 Cookie 进入 Nginx。Nginx 使用 auth_request 模块向 oauth2-proxy 校验每个请求,未登录用户会被重定向到 OIDC 登录页面。
以下是一个 oauth2-proxy 的启动示例,使用 OIDC Provider 并关闭邮箱域名限制,因为企业身份源通常包含多个域名。
docker run -d --name oauth2-proxy -p 4180:4180 \ -e OAUTH2_PROXY_PROVIDER=oidc \ -e OAUTH2_PROXY_CLIENT_ID=neo4j-browser \ -e OAUTH2_PROXY_REDIRECT_URL=https://neo4j.ipipp.com/oauth2/callback \ -e OAUTH2_PROXY_OIDC_ISSUER_URL=https://idp.ipipp.com/realms/graphdb \ -e OAUTH2_PROXY_EMAIL_DOMAINS=* \ -e OAUTH2_PROXY_COOKIE_SECURE=true \ -e OAUTH2_PROXY_UPSTREAMS=http://127.0.0.1:7474
Nginx 的配置需要把 /oauth2/ 路径转发给 oauth2-proxy 处理登录回调,其余路径先经过 auth_request 校验,再转发到 Neo4j 的 7474 端口。示例配置如下。
server {
listen 443 ssl;
server_name neo4j.ipipp.com;
location /oauth2/ {
proxy_pass http://127.0.0.1:4180/oauth2/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
location / {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
proxy_pass http://127.0.0.1:7474;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
}
这个方案的典型问题是重定向循环。很大一部分原因是 Nginx 转发给上游时没有正确传递 X-Forwarded-Proto,或者 oauth2-proxy 的回调地址写成了 HTTP,而实际用户通过 HTTPS 访问。出现循环时先检查 oauth2-proxy 日志中的回调地址,再确认 Nginx 是否把请求转发到了 oauth2-proxy。
另一个常见问题是 OIDC 发现失败。Neo4j 内置配置和 oauth2-proxy 都依赖 /.well-known/openid-configuration 这个发现文档。可以先在 Neo4j 所在机器上用命令行工具访问该地址,确认没有 TLS 证书问题或网络策略拦截。发现文档访问不了时,登录流程会在最开始就中断,通常表现为浏览器一直停留在空白页或反复跳转但不出现登录表单。
无论使用内置 OIDC 还是 oauth2-proxy,单点登录只解决了认证与浏览器会话问题。生产环境中应当继续遵循最小权限原则,为自动化任务保留独立服务账号,并对 OIDC 用户映射后的图数据库角色做定期审计,避免统一身份体系引入新的权限扩散风险。