配置 Neo4j 单点登录 (SSO)

Neo4j 支持通过实现 OpenID Connect (OIDC) 标准的身份提供程序进行 SSO 认证和授权。本页面提供了如何为多个身份提供程序配置单点登录 (SSO) 的详细示例。它还提供了在配置 SSO 时遇到的常见问题和解决方案。

以下配置是为在 http://localhost:7474/browser/ 上服务的 Neo4j Browser 而设计的(在 localhost 上启动数据库时的默认 URL)。

因此,在身份提供程序中重现这些配置时,您必须修改重定向 URI 以包含服务您的 Neo4j Browser 应用程序的 URI。例如

http://localhost:7474/browser/?idp_id={provider}&auth_flow_step=redirect_uri

SSO 工作方式如下

  1. 服务器 (Neo4j DBMS) 联系身份提供程序(Okta、Entra ID、Google 等),并从提供程序获取 JSON Web Keys (JWKs)。

  2. 客户端(例如 Bloom、Neo4j Browser 等)向用户请求凭证并联系身份提供程序。

  3. 身份提供程序响应一个 JSON Web Token (JWT),这是一个包含与用户相关的字段(声明)的 JSON 文件(电子邮件、受众、组等)。

  4. 客户端向服务器提供 JWT,服务器使用 JWKs 验证其签名。

  5. 您可以选择通过在 _neo4j.conf_ 文件中将 dbms.security.require_local_user 设置为 true,并使用 Cypher 为您希望进行认证和授权控制的用户配置 认证提供程序,从而在用户级别控制认证和授权。此设置要求,在用户可以使用相关认证提供程序进行认证和授权之前,数据库中必须存在附加了该认证提供程序的用户。有关在此模式下如何修改或创建用户的信息,请参阅 管理用户
    此模式允许您使用 Cypher 执行以下操作

    1. 暂停 SSO 用户。

    2. 为 SSO 用户设置主数据库。

    3. 为 SSO 用户设置一个用户友好的名称(而不是依赖外部标识符)。

    4. 为 SSO 用户设置密码。

    5. 为 SSO 用户设置密码更改要求。

更多信息和示例,请参阅 使用认证提供程序在用户级别配置 SSO

即使为 username 使用不同的声明,JWT 也必须始终包含 sub 的值。它是唯一保证唯一且稳定的声明。其他声明,例如 emailpreferred_username,安全性较低,并且可能会随时间变化。它们不应用于认证。在混合授权配置中,Neo4j 可能会根据此用户名值向用户分配权限。因此,不建议将用户名声明从 sub 更改。

Okta

以下示例展示了如何使用访问令牌和 ID 令牌配置 Okta 进行认证和授权。本文假设您正在使用 Okta 开发者版服务。有关如何使用组声明自定义从 Okta 返回的令牌的完整指南,请参阅 Okta 官方文档

配置客户端

  1. 从 Okta 仪表板的左侧导航到应用程序,然后点击创建应用集成

  2. 登录方法选择 OIDC - OpenID Connect,应用程序类型选择 Single-Page Application

  3. 点击下一步

  4. 使用适当的重定向 URI 配置客户端。

    1. 为应用集成添加名称。

    2. 添加登录重定向 URI,例如 http://localhost:7474/browser/?idp_id=okta&auth_flow_step=redirect_uri。此 URI 将在成功认证后接受返回的令牌响应。

  5. 添加注销重定向 URI,例如 http://localhost:7474/browser/

  6. 分配部分,暂时选择跳过组分配

  7. 点击保存

  8. 记下客户端 ID。稍后在 _neo4j.conf_ 文件中配置 Okta 参数和知名 OpenID Connect 端点时会用到它。

将 Okta 组分配给应用程序

  1. 从 Okta 仪表板的左侧导航到仪表板 → 目录 → 组,然后点击添加组

  2. 为组添加一个名称,例如 engineers,然后点击保存

  3. 点击您刚创建的组,然后点击分配人员

  4. 将用户添加到组。可以在创建用户时或通过编辑组将用户添加到组。

  5. 将组分配给应用程序。

    1. 点击应用程序,然后点击分配应用程序

    2. 选择您之前创建的应用程序,然后点击分配

访问令牌

此示例展示了如何使用访问令牌配置 Okta 进行认证和授权,以及如何配置 Neo4j 来使用它们。

向访问令牌添加组声明

  1. 从 Okta 仪表板的左侧导航到安全 → API

  2. 点击默认授权服务器(显示 api://default 作为受众的服务器),以在访问令牌中返回 groups 声明。

    1. 声明选项卡上,点击添加声明

    2. 添加一个名为 groups 的声明。

    3. 值类型下拉菜单中,选择

    4. 从“过滤器”下拉菜单中,选择匹配正则表达式,并将值设置为 .*

    5. 点击创建

配置 Neo4j

  1. 通过在 _neo4j.conf_ 文件中配置以下设置,将 Neo4j 配置为使用 Okta 认证

    dbms.security.authentication_providers=oidc-okta
    dbms.security.authorization_providers=oidc-okta
    dbms.security.oidc.okta.display_name=Okta
    dbms.security.oidc.okta.auth_flow=pkce
    dbms.security.oidc.okta.well_known_discovery_uri=https://dev-54101110.okta.com/oauth2/default/.well-known/oauth-authorization-server
    dbms.security.oidc.okta.audience=api://default
    dbms.security.oidc.okta.claims.username=sub
    dbms.security.oidc.okta.claims.groups=groups
    dbms.security.oidc.okta.params=client_id=0oao2rybx5hIERt5W5d7;response_type=code;scope=openid profile email
    dbms.security.oidc.okta.authorization.group_to_role_mapping= "engineers" = admin; \
                                                                 "collaborators" = reader

    token_type_principaltoken_type_authentication 被省略,这意味着改用访问令牌。

  2. 使用数据库中具有 admin 角色的 engineer 角色用户的电子邮件,通过您的 Okta SSO 凭据登录。

    oidc okta successful login
    图 1. Okta OIDC 成功登录

ID 令牌

此示例展示了如何使用 ID 令牌配置 Okta 进行认证和授权,以及如何配置 Neo4j 来使用它们。

向 ID 令牌添加组声明

您可以将组声明添加到 ID 令牌,以配置使用 ID 令牌进行认证和授权。

  1. 从 Okta 仪表板的左侧导航到安全 → API

  2. 点击默认授权服务器(显示 api://default 作为受众的服务器),以在访问令牌中返回 groups 声明。

    1. 声明选项卡上,点击添加声明

    2. 添加一个名为 groups 的声明。

    3. 包含在令牌类型中下拉菜单中,选择ID 令牌

    4. 值类型下拉菜单中,选择

    5. 从“过滤器”下拉菜单中,选择匹配正则表达式,并将值设置为 .*

    6. 点击创建

  3. 添加一个名为 userid 的声明,值类型为 User ID

    userid 声明默认不包含在 ID 令牌中,不像访问令牌的默认 sub 声明,因此您需要手动添加它。您给声明的名称也需要写在 _neo4j.conf_ 文件中的配置 dbms.security.oidc.okta.claims.username=userid 中。

    1. 点击添加声明

    2. 添加一个名为 userid 的声明。

    3. 包含在令牌类型中下拉菜单中,选择ID 令牌

    4. 值类型下拉菜单中,选择表达式

    5. 字段中,输入 (appuser !=null) ? appuser.userName : app.clientId

    6. 点击创建

配置 Neo4j

  1. 通过在 _neo4j.conf_ 文件中配置以下设置,将 Neo4j 配置为使用 Okta 认证

    dbms.security.authentication_providers=oidc-okta, native
    dbms.security.authorization_providers=oidc-okta
    dbms.security.oidc.okta.display_name=Okta
    dbms.security.oidc.okta.auth_flow=pkce
    dbms.security.oidc.okta.well_known_discovery_uri=https://dev-54101110.okta.com/oauth2/default/.well-known/oauth-authorization-server
    dbms.security.oidc.okta.audience=0oao2rybx5hIERt5W5d7
    dbms.security.oidc.okta.claims.username=userid
    dbms.security.oidc.okta.claims.groups=groups
    dbms.security.oidc.okta.params=client_id=0oao2rybx5hIERt5W5d7;response_type=code;scope=openid profile email
    dbms.security.oidc.okta.authorization.group_to_role_mapping="admin_group" = admin;
    dbms.security.oidc.okta.config=token_type_principal=id_token;token_type_authentication=id_token

    您可以在应用程序的登录选项卡下的OpenID Connect ID 令牌部分找到受众参数。

  2. (可选)如果您想在用户级别控制认证和授权,请在 _neo4j.conf_ 文件中将 dbms.security.require_local_user 设置为 true。此设置要求,在用户可以使用相关认证提供程序进行认证和授权之前,数据库中必须存在附加了该认证提供程序的用户。有关在此模式下如何创建用户的信息,请参阅 创建用户

    例如,要创建可以使用 nativeokta 进行认证,并使用 Okta(如第 3 步中所配置)进行授权的用户 jake,您可以使用以下 Cypher 查询

    CREATE USER jake
    SET HOME DATABASE 'jakesHomeDb'
    SET AUTH 'oidc-okta' {SET ID 'jakesUniqueOktaUserId'} // `jakesUniqueOktaUserId` must match the value of the claim that you configured via dbms.security.oidc.okta.claims.username
    SET AUTH 'native' {SET PASSWORD 'changeme' SET PASSWORD CHANGE REQUIRED}

Microsoft Entra ID(原 Azure Active Directory)

以下示例展示了如何使用访问令牌和 ID 令牌配置 Microsoft Entra ID 进行认证和授权。

注册应用程序

  1. 登录 Azure 门户

  2. 点击Microsoft Entra ID 并导航到管理 → 应用注册

  3. 点击新建注册

  4. 为您的应用程序输入一个名称,例如 Neo4j SSO

  5. 选择支持的账户类型下,选择 仅此组织目录中的账户(仅限默认目录 - 单租户)

  6. 重定向 URI 下,选择 单页应用程序 (SPA) 并输入重定向 URI: http://localhost:7474/browser/?idp_id=azure&auth_flow_step=redirect_uri 重定向 URI 将在成功认证后接受返回的令牌响应。

  7. 点击注册

访问令牌

此示例展示了如何配置 Neo4j 以使用 Entra ID 访问令牌进行认证和授权。

配置 Entra ID

  1. 应用注册页面,选择您刚创建的应用程序。

  2. 从左侧菜单导航到管理 → 令牌配置

    1. 点击添加组声明

    2. 选择分配给应用程序的组(推荐用于大型企业,以避免超出令牌可发出的组数量限制)以包含在您的访问令牌中。

    3. 保存您的更改。

  3. 导航到公开 API 并点击添加范围

    首次点击添加范围按钮时,您会看到一个新窗格,提示您需要先添加一个 _Application ID URI_。您可以在应用程序的概述页面找到它。它是一个 GUID,类似于:api://<GUID>。该 GUID 是您应用程序的唯一标识符。

  4. 设置 _Application ID URI_ 后,点击保存并继续

  5. 填写添加范围窗格中的所有必填字段。

    1. 输入新的范围名称(例如 access-token)、管理员同意显示名称管理员同意描述

    2. 确保已选择已启用范围状态。

    3. 再次选择添加范围按钮以创建新范围。您可以添加 API 支持的所有范围。请记下它们以备后用。

配置 Neo4j

您可以通过在 _neo4j.conf_ 文件中配置以下设置,将 Neo4j 配置为使用 Entra ID 进行认证

# Configure the access_token
dbms.security.oidc.azure.config=principal=unique_name;code_challenge_method=S256;token_type_principal=access_token;token_type_authentication=access_token
# Configure the OIDC token endpoint with the Directory (tenant) ID
dbms.security.oidc.azure.token_endpoint=https://login.microsoftonline.com/54e85725-ed2a-49a4-a19e-11c8d29f9a0f/oauth2/v2.0/token
# Configure the iss claim in the id token with the Directory (tenant) ID
# Make sure you add the trailing slash (`/`) at the end of the URL or this operation might fail.
dbms.security.oidc.azure.issuer=https://sts.windows.net/54e85725-ed2a-49a4-a19e-11c8d29f9a0f/
# Provide the Entra ID parameters, such as client_id, response_type, scope, etc.
dbms.security.oidc.azure.params=client_id=4376dc8b-b5af-424f-9ada-c1c1b2d416b9;response_type=code;scope=openid profile email api://4376dc8b-b5af-424f-9ada-c1c1b2d416b9/access-token

ID 令牌

此示例展示了如何配置 Neo4j 以使用 Entra ID ID 令牌进行认证和授权。

配置 Neo4j

  1. 应用注册页面,选择您在 注册应用程序 中创建的应用程序。

  2. 在应用程序概述页面,复制应用程序(客户端)ID 值,并使用它在 _neo4j.conf_ 文件中配置以下属性

    dbms.security.oidc.azure.audience=4376dc8b-b5af-424f-9ada-c1c1b2d416b9
    dbms.security.oidc.azure.params=client_id=4376dc8b-b5af-424f-9ada-c1c1b2d416b9;response_type=code;scope=openid profile email
  3. 在应用程序的概述页面,点击终结点选项卡,然后复制OpenID Connect 元数据文档 URI:使用它在 _neo4j.conf_ 文件中配置 well_known_discovery_uri

    dbms.security.oidc.azure.well_known_discovery_uri=https://login.microsoftonline.com/54e85725-ed2a-49a4-a19e-11c8d29f9a0f/v2.0/.well-known/openid-configuration
  4. 在 _neo4j.conf_ 文件中配置 Neo4j 以使用 Entra ID 认证

    dbms.security.authentication_providers=oidc-azure
    dbms.security.authorization_providers=oidc-azure
    dbms.security.oidc.azure.display_name=Azure
    dbms.security.oidc.azure.auth_flow=pkce
    dbms.security.oidc.azure.config=token_type_principal=id_token;token_type_authentication=id_token
  5. 配置应使用哪个 JWT 声明作为用户名。可能的值为 subemailpreferred_username

    sub 是唯一保证唯一且稳定的声明。详情请参阅 Microsoft 文档 以及 OpenId 规范

    dbms.security.oidc.azure.claims.username=sub

将 Entra 组映射到 Neo4j 角色

决定您是想直接使用 Entra 组还是 Entra 应用程序角色。

如果您已经将用户分配到这些组,并且希望在 _neo4j.conf_ 文件中执行组到角色的映射,那么直接使用 Entra 组可能会很方便。

Entra 应用程序角色允许在 Neo4j 角色和组之间建立一层分离。当使用应用程序角色时,只有与 Neo4j 相关的角色才会在 JWT 令牌中发送。这可以防止应用程序之间权限泄露。JWT 令牌还存在每个用户每个令牌最多 200 个角色的限制,通过仅发送相关的应用程序角色可以避免此限制。

有关 Entra ID 应用程序角色的详细信息,请参阅 Microsoft 文档

直接使用 Entra 组

  1. 应用注册页面,选择您的应用程序。

  2. 从左侧菜单导航到管理 → 清单

  3. 验证服务器是否配置为在 JWT 身份令牌中返回组对象 ID

    "groupMembershipClaims": "SecurityGroup, ApplicationGroup",
  4. 从左侧菜单导航到管理 → 组

  5. 创建组并将用户分配给它们。记下对象 ID 列。

  6. 配置 Entra 组对象 ID 到 Neo4j 角色的映射。详情请参阅 将身份提供程序组映射到 Neo4j 角色

    dbms.security.oidc.azure.authorization.group_to_role_mapping= "e8b6ddfa-688d-4ace-987d-6cc5516af188" = admin; \
                                                                  "9e2a31e1-bdd1-47fe-844d-767502bd138d" = reader
  7. 配置 Neo4j 使用 JWT 令牌中的 groups 字段。

    dbms.security.oidc.azure.claims.groups=groups

使用 Entra ID 应用程序角色

  1. 从左侧菜单导航到应用程序角色,并将 Neo4j 角色添加到 Microsoft Entra ID。

    1. 点击创建应用程序角色

    2. 填写字段

      1. 显示名称: admin

      2. 允许的成员类型: 用户/组

      3. : admin
        列必须与 Neo4j 角色对应,或在 _neo4j.conf_ 文件中进行映射。

      4. 描述: Neo4j 管理员角色

    3. 点击应用

  2. 对您想添加的其他角色重复上一步。

  3. 在 _neo4j.conf_ 文件中配置 Entra 应用程序角色到 Neo4j 角色的映射。详情请参阅 将身份提供程序组映射到 Neo4j 角色

    dbms.security.oidc.azure.authorization.group_to_role_mapping= "managers" = admin; \
                                                                  "engineers" = reader
  4. 配置 Neo4j 使用 JWT 令牌中的 roles 字段。

    dbms.security.oidc.azure.claims.groups=roles
  5. (可选)如果您想在用户级别控制认证和授权,请在 _neo4j.conf_ 文件中将 dbms.security.require_local_user 设置为 true。此设置要求,在用户可以使用相关认证提供程序进行认证和授权之前,数据库中必须存在附加了该认证提供程序的用户。有关在此模式下如何创建用户的信息,请参阅 创建用户

    例如,要创建可以使用 Azure 进行认证和授权的用户 jake,您可以使用以下 Cypher 查询

    CREATE USER jake
    SET HOME DATABASE 'jakesHomeDb'
    SET AUTH 'oidc-azure' {SET ID 'jakesUniqueAzureUserId'} // `jakesUniqueAzureUserId` must match the value of the claim that you configured via dbms.security.oidc.azure.claims.username

Google

ID 令牌

此示例展示了如何结合原生授权,使用 Google OpenID Connect 进行基于 ID 令牌的认证。

  1. 配置客户端和重定向 URI

    oidc google client creation
    图 2. Google OIDC 客户端创建
    oidc google client config
    图 3. Google OIDC 客户端配置

    SSO 授权不适用于 Google,因为 Google 返回的 JWT 不包含用户所属组的信息,也无法配置。因此,建议通过在 Neo4j 中创建用户的原生版本来使用原生(或其他形式)授权。

  2. 通过在 _neo4j.conf_ 文件中设置以下配置,将 Neo4j 配置为使用 Google 认证

    dbms.security.authentication_providers=oidc-google
    dbms.security.authorization_providers=native
    dbms.security.oidc.google.display_name=Google
    dbms.security.oidc.google.auth_flow=pkce
    dbms.security.oidc.google.well_known_discovery_uri=https://#/.well-known/openid-configuration
    dbms.security.oidc.google.audience=345461137297-v9brpjmgbvbm3d5s9fq65tktevosd3rn.apps.googleusercontent.com
    dbms.security.oidc.google.claims.username=email
    dbms.security.oidc.google.params=client_id=345461137297-v9brpjmgbvbm3d5s9fq65tktevosd3rn.apps.googleusercontent.com;response_type=code;scope=openid profile email
    dbms.security.oidc.google.token_params=client_secret=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
    dbms.security.oidc.google.config=token_type_principal=id_token;token_type_authentication=id_token
  3. 使用以下选项之一,在数据库中创建一个可以原生认证和授权的用户,以便能够授予用户原生授权中的角色。

    此方法依赖于存在一个可以原生认证的管理员用户,然后通过 认证提供程序 创建权限较低的用户,这些用户只能使用 oidc-google 进行认证,但会获得使用 native 授权授予他们的角色。

    当数据库 首次启动 时,默认会创建一个名为 neo4j 的管理员用户。

    1. 在 _neo4j.conf_ 文件中,暂时仅为 admin 用户启用原生认证,并启用用户级别的认证和授权控制

      dbms.security.authentication_providers=oidc-google, native
      dbms.security.require_local_user=true

      这将切换到 _用户认证提供程序_ 模式,即用户只有在数据库中拥有相应的认证提供程序时才能进行认证和授权。

    2. 创建一个只能使用 oidc-google 进行认证和授权的用户

      CREATE USER jake
      SET HOME DATABASE 'jakesHomeDb'
      SET AUTH 'oidc-google' {SET ID 'jakesUniqueGoogleUserId'} (1)
      1 jakesUniqueGoogleUserId 必须与您通过 dbms.security.oidc.google.claims.username 配置的声明值匹配。
    3. 授予用户 jake 角色,例如 reader

      GRANT ROLE reader TO jake

      用户隐式地获得了 native 授权,因为 native 在授权提供程序列表中,并且您已明确授予用户一个角色。

    4. 一旦您以这种方式设置了用户,就可以完全禁用数据库的原生认证。这将阻止所有用户(包括管理员)使用用户名和密码登录

      dbms.security.authentication_providers=oidc-google

    另外,如果您不使用认证提供程序,您可以暂时启用 native 认证来创建一个通过 SSO 认证的管理员用户 alice,然后该用户可以创建只能使用 SSO 进行认证的其他用户。

    1. 暂时启用 native 认证

      dbms.security.authentication_providers=oidc-google, native
    2. 创建一个通过 SSO 认证的 admin 用户(在本例中,必须在 Google SSO 提供程序中设置一个与 alice@neo4j-test.com 对应的用户,并且必须知道其凭据)

      CREATE USER `alice@neo4j-test.com` SET PASSWORD 'secretpassword';
      GRANT ROLE admin to `alice@neo4j-test.com`;
    3. 禁用数据库的原生认证,以防止用户使用用户名和密码登录

      dbms.security.authentication_providers=oidc-google
    4. admin 用户 alice@neo4j-test.com 的身份通过 Google SSO 登录。

    5. 创建其他只能使用 oidc-google 进行认证,并获得使用 native 授权授予的角色。

      CREATE USER jakesUniqueGoogleUserId (1)
      SET HOME DATABASE 'jakesHomeDb'
      SET PASSWORD 'secretpassword' SET PASSWORD CHANGE NOT
      REQUIRED
      1 jakesUniqueGoogleUserId 必须与您通过 dbms.security.oidc.google.claims.username 配置的声明值匹配。
    6. 使用原生授权授予用户角色

      GRANT ROLE reader TO jakesUniqueGoogleUserId

常见问题

何时应使用 pkce 作为认证流程?

假设客户端(Neo4j Browser 或 Bloom)可以通过公共互联网访问,请始终使用 pkce 认证流程而不是 implicit,因为后者要求客户端的密钥可供公共客户端使用。通常,如果两种流程都可用,建议选择 pkce,因为它比 implicit 更安全。

如果配置中列出了客户端密钥,Google 认证是否安全?

是的。Google 使用 PKCE 流程,但身份提供程序有时也会使用客户端密钥来确保请求令牌的客户端就是使用该令牌的客户端(PKCE 无法保证这一点)。客户端密钥是公开的,因此不会增加任何额外的安全性,但 pkce 流程提供了足够的安全性。

无法解析类型为 "access_token" 的 JWT

在 Browser 上收到消息 Failed to get credentials: Could not parse JWT of type "access_token" 时,这可能意味着提供程序只接受 ID 令牌。

oidc access token error
图 4. 无法解析类型为 access_token 的 JWT

在您的 _neo4j.conf_ 中更改为 ID 令牌

dbms.security.oidc.{{provider}}.config=token_type_principal=id_token;token_type_authentication=id_token

何时应使用身份令牌与访问令牌?

通常,如果可能,使用访问令牌更安全,因为其生命周期较短。如果身份提供程序上的授权权限发生更改,Neo4j 将无法授权。Neo4j Browser 将比使用 ID 令牌更快地尝试重新连接并反映更改的权限。

JWT 声明的调试日志记录

在设置 OIDC 集成时,有时需要进行故障排除。在这种情况下,查看身份提供程序提供的 JWT 中包含的声明可能很有用。

要在安全日志中以 DEBUG 级别启用这些声明的日志记录,请将 dbms.security.logs.oidc.jwt_claims_at_debug_level_enabled 设置为 true,并将安全日志级别设置为 DEBUG。您可以在 _<NEO4J_HOME>/conf/server-logs.xml_ 中执行此操作。

如果您需要更多关于如何设置和管理安全日志的信息,请参阅 配置安全日志

确保在生产环境中将 dbms.security.logs.oidc.jwt_claims_at_debug_level_enabled 设置回 false,以避免不必要的敏感信息日志记录。另外,请记住身份提供程序在 JWT 中提供的一组声明可能会随时间变化。

如何调试其他配置问题

除了 Neo4j 路径下 _logs/debug.log_ 和 _logs/security.log_ 中可用的日志外,在使用 Bloom 或 Neo4j Browser 执行 SSO 认证流程时,您还可以使用 Web 浏览器中的 Web 开发控制台。这可能会揭示潜在问题,例如下面示例身份提供程序和跨源请求策略中显示的问题

oidc cors error
图 5. CORS 错误

解决方案涉及将重定向域添加到提供程序允许域列表中(在本例中为 localhost:8080

oidc cors error solution
图 6. 允许提供程序上的重定向域的 CORS 错误解决方案