Help us learn about your current experience with the documentation. Take the survey.

使用 OpenID Connect 作为身份验证提供商

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab Self-Managed

您可以将 GitLab 作为客户端应用程序,使用 OpenID Connect 作为 OmniAuth 提供商。

要启用 OpenID Connect OmniAuth 提供商,您必须向 OpenID Connect 提供商注册您的应用程序。 OpenID Connect 提供商会为您提供客户端详情和密钥供您使用。

  1. 在您的 GitLab 服务器上,打开配置文件。

对于 Linux 软件包安装:

   sudo editor /etc/gitlab/gitlab.rb

对于自编译安装:

   cd /home/git/gitlab
   sudo -u git -H editor config/gitlab.yml
  1. 配置通用设置openid_connect 添加为单点登录提供商。这将为没有现有 GitLab 账户的用户启用即时账户配置。

  2. 添加提供商配置。

对于 Linux 软件包安装:

   gitlab_rails['omniauth_providers'] = [
     {
       name: "openid_connect", # 请勿更改此参数
       label: "Provider name", # 登录按钮的可选标签,默认为 "Openid Connect"
       icon: "<custom_provider_icon>",
       args: {
         name: "openid_connect",
         scope: ["openid","profile","email"],
         response_type: "code",
         issuer: "<your_oidc_url>",
         discovery: true,
         client_auth_method: "query",
         uid_field: "<uid_field>",
         send_scope_to_token_endpoint: "false",
         pkce: true,
         client_options: {
           identifier: "<your_oidc_client_id>",
           secret: "<your_oidc_client_secret>",
           redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback"
         }
       }
     }
   ]

对于具有多个身份提供商的 Linux 软件包安装:

   { 'name' => 'openid_connect',
     'label' => '...',
     'icon' => '...',
     'args' => {
       'name' => 'openid_connect',
       'strategy_class': 'OmniAuth::Strategies::OpenIDConnect',
       'scope' => ['openid', 'profile', 'email'],
       'discovery' => true,
       'response_type' => 'code',
       'issuer' => 'https://...',
       'client_auth_method' => 'query',
       'uid_field' => '...',
       'client_options' => {
         `identifier`: "<your_oidc_client_id>",
         `secret`: "<your_oidc_client_secret>",
         'redirect_uri' => 'https://.../users/auth/openid_connect/callback'
      }
    }
   },
   { 'name' => 'openid_connect_2fa',
     'label' => '...',
     'icon' => '...',
     'args' => {
       'name' => 'openid_connect_2fa',
       'strategy_class': 'OmniAuth::Strategies::OpenIDConnect',
       'scope' => ['openid', 'profile', 'email'],
       'discovery' => true,
       'response_type' => 'code',
       'issuer' => 'https://...',
       'client_auth_method' => 'query',
       'uid_field' => '...',
       'client_options' => {
        ...
        'redirect_uri' => 'https://.../users/auth/openid_connect_2fa/callback'
      }
    }
   }

对于自编译安装:


- { name: 'openid_connect', # 请勿更改此参数
         label: 'Provider name', # 登录按钮的可选标签,默认为 "Openid Connect"
         icon: '<custom_provider_icon>',
         args: {
           name: 'openid_connect',
           scope: ['openid','profile','email'],
           response_type: 'code',
           issuer: '<your_oidc_url>',
           discovery: true,
           client_auth_method: 'query',
           uid_field: '<uid_field>',
           send_scope_to_token_endpoint: false,
           pkce: true,
           client_options: {
             identifier: '<your_oidc_client_id>',
             secret: '<your_oidc_client_secret>',
             redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback'
           }
         }
       }

有关每个配置选项的更多信息,请参考 OmniAuth OpenID Connect 使用文档OpenID Connect Core 1.0 规范

  1. 对于提供商配置,请更改提供商的值以匹配您的 OpenID Connect 客户端设置。使用以下内容作为指南:
  • <your_oidc_label> 是显示在登录页面上的标签。

  • <custom_provider_icon>(可选)是显示在登录页面上的图标。 主要社交登录平台的图标已内置在 GitLab 中, 但您可以通过指定此参数覆盖这些图标。GitLab 接受 本地路径和绝对 URL。 GitLab 包含大多数主要社交登录平台的图标, 但您可以通过指定外部 URL 或 自己图标文件的绝对或相对路径来覆盖这些图标。

  • 对于本地绝对路径,将提供商配置为 icon: <path>/<to>/<your-icon>

  • 将图标文件存储在 /opt/gitlab/embedded/service/gitlab-rails/public/<path>/<to>/<your-icon>

  • 通过 https://gitlab.example/<path>/<to>/<your-icon> 访问图标文件。

  • 对于本地相对路径,将提供商配置为 icon: <your-icon>

  • 将图标文件存储在 /opt/gitlab/embedded/service/gitlab-rails/public/images/<your-icon>

  • 通过 https://gitlab.example.com/images/<your-icon> 访问图标文件。

  • <your_oidc_url>(可选)是指向 OpenID Connect 提供商的 URL(例如 https://example.com/auth/realms/your-realm)。 如果未提供此值,URL 将从 client_options 按以下格式构建:<client_options.scheme>://<client_options.host>:<client_options.port>

  • 如果 discovery 设置为 true,OpenID Connect 提供商将尝试自动 使用 <your_oidc_url>/.well-known/openid-configuration 发现客户端选项。 默认为 false

  • client_auth_method(可选)指定用于 向 OpenID Connect 提供商验证客户端身份的方法。

  • 支持的值包括:

  • basic - HTTP 基本身份验证。

  • jwt_bearer - 基于 JWT 的身份验证(私钥和客户端密钥签名)。

  • mtls - 双向 TLS 或 X.509 证书验证。

  • 任何其他值将在请求正文中发送客户端 ID 和密钥。

  • 如果未指定,此值默认为 basic

  • <uid_field>(可选)是来自 user_info.raw_attributes 的字段名称,用于定义 uid 的值(例如 preferred_username)。 如果您未提供此值,或 user_info.raw_attributes 中缺少具有配置值的字段, uid 将使用 sub 字段。

  • send_scope_to_token_endpoint 默认为 true,因此 scope 参数 通常包含在对令牌端点的请求中。 但是,如果您的 OpenID Connect 提供商不接受此类请求中的 scope 参数, 请将此设置为 false

  • pkce(可选):启用代码交换证明密钥 (PKCE)。在 GitLab 15.9 中可用。

  • client_options 是 OpenID Connect 客户端特定选项。具体包括:

  • identifier 是在 OpenID Connect 服务提供商中配置的客户端标识符。

  • secret 是在 OpenID Connect 服务提供商中配置的客户端密钥。例如, OmniAuth OpenID Connect 需要此密钥。如果服务提供商不需要密钥, 提供任意值即可,它将被忽略。

  • redirect_uri 是成功登录后将用户重定向到的 GitLab URL (例如 http://example.com/users/auth/openid_connect/callback)。

  • end_session_endpoint(可选)是结束 会话的端点 URL。如果自动发现被禁用或失败,您可以提供此 URL。

  • 以下 client_options 是可选的,除非自动发现被禁用或失败:

  • authorization_endpoint 是授权最终用户的端点 URL。

  • token_endpoint 是提供访问令牌的端点 URL。

  • userinfo_endpoint 是提供用户信息的端点 URL。

  • jwks_uri 是令牌签名者发布其密钥的端点 URL。

  1. 保存配置文件。

  2. 要使更改生效,如果您:

在登录页面上,常规登录表单下方有一个 OpenID Connect 选项。 选择此选项开始身份验证过程。OpenID Connect 提供商 会要求您登录并授权 GitLab 应用程序(如果客户端需要确认)。 您将被重定向到 GitLab 并完成登录。

示例配置

以下配置说明了在使用 Linux 软件包安装时, 如何为不同提供商设置 OpenID。

配置 Google

有关更多详细信息,请参阅 Google 文档

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect", # do not change this parameter
    label: "Google OpenID", # optional label for login button, defaults to "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer: "https://accounts.google.com",
      client_auth_method: "query",
      discovery: true,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "<YOUR PROJECT CLIENT ID>",
        secret: "<YOUR PROJECT CLIENT SECRET>",
        redirect_uri: "https://example.com/users/auth/openid_connect/callback",
       }
     }
  }
]

配置 Microsoft Azure

Microsoft Azure 的 OpenID Connect (OIDC) 协议使用 Microsoft 身份平台 (v2) 端点。 要开始配置,请登录 Azure 门户。对于您的应用, 需要以下信息:

注册 Microsoft Azure 应用程序时,必须授予 API 权限以允许 GitLab 检索所需详细信息。至少需要提供 openidprofileemail 权限。 更多信息请参阅 Microsoft 关于为 Web API 配置应用权限的文档

Azure 配置的所有账户必须定义电子邮件地址。如果未定义电子邮件地址,Azure 会分配随机生成的地址。如果您已配置域名注册限制,此随机地址可能会阻止账户创建。

Linux 包安装的示例配置块:

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect", # do not change this parameter
    label: "Azure OIDC", # optional label for login button, defaults to "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com/<YOUR-TENANT-ID>/v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "<YOUR APP CLIENT ID>",
        secret: "<YOUR APP CLIENT SECRET>",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
      }
    }
  }
]

Microsoft 已记录其平台如何与 OIDC 协议 配合使用。

Microsoft Entra 自定义签名密钥

如果您的应用因使用 SAML 声明映射功能 而具有自定义签名密钥,必须按以下方式配置 OpenID 提供程序:

  • 通过省略 args.discovery 或将其设置为 false 来禁用 OpenID Connect Discovery。

  • client_options 中指定以下内容:

  • 带有 appid 查询参数的 jwks_urihttps://login.microsoftonline.com/<YOUR-TENANT-ID>/discovery/v2.0/keys?appid=<YOUR APP CLIENT ID>

  • end_session_endpoint

  • authorization_endpoint

  • userinfo_endpoint

Linux 包安装的示例配置:

gitlab_rails['omniauth_providers'] = [
 {
    name: "openid_connect", # do not change this parameter
    label: "Azure OIDC", # optional label for login button, defaults to "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com/<YOUR-TENANT-ID>/v2.0",
      client_auth_method: "basic",
      discovery: false,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "<YOUR APP CLIENT ID>",
        secret: "<YOUR APP CLIENT SECRET>",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback",
        end_session_endpoint: "https://login.microsoftonline.com/<YOUR-TENANT-ID>/oauth2/v2.0/logout",
        authorization_endpoint: "https://login.microsoftonline.com/<YOUR-TENANT-ID>/oauth2/v2.0/authorize",
        token_endpoint: "https://login.microsoftonline.com/<YOUR-TENANT-ID>/oauth2/v2.0/token",
        userinfo_endpoint: "https://graph.microsoft.com/oidc/userinfo",
        jwks_uri: "https://login.microsoftonline.com/<YOUR-TENANT-ID>/discovery/v2.0/keys?appid=<YOUR APP CLIENT ID>"
      }
    }
  }
]

如果遇到带有 KidNotFound 消息的身份验证失败,这 可能是由于缺少或错误的 appid 查询 参数导致的。如果 Microsoft 返回的 ID 令牌无法通过 jwks_uri 端点提供的密钥进行验证,GitLab 会引发该错误。

更多信息请参阅 Microsoft Entra 关于验证令牌的文档

迁移到通用 OpenID Connect 配置

您可以从 azure_activedirectory_v2azure_oauth2 迁移到通用 OpenID Connect 配置。

首先,设置 uid_fielduid_field 和可作为 uid_field 选择的 sub 声明因提供程序而异。未设置 uid_field 的登录会导致在 GitLab 中创建额外的身份,这些身份需要手动修改:

| 提供程序 | uid_field | 支持信息 |

|—————————————————————————————————————–|——-|———————————————————————–|

| omniauth-azure-oauth2 | sub | info 对象中提供额外的 oidtid 属性。 |

| omniauth-azure-activedirectory-v2 | oid | 迁移时必须将 oid 配置为 uid_field。 |

| omniauth_openid_connect | sub | 指定 uid_field 以使用其他字段。 |

要迁移到通用 OpenID Connect 配置,必须更新配置。

对于 Linux 包安装,按如下方式更新配置:

gitlab_rails['omniauth_providers'] = [
  {
    name: "azure_oauth2",
    label: "Azure OIDC", # optional label for login button, defaults to "Openid Connect"
    args: {
      name: "azure_oauth2", # this matches the existing azure_oauth2 provider name, and only the strategy_class immediately below configures OpenID Connect
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com/<YOUR-TENANT-ID>/v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "sub",
      send_scope_to_token_endpoint: "false",
      client_options: {
        identifier: "<YOUR APP CLIENT ID>",
        secret: "<YOUR APP CLIENT SECRET>",
        redirect_uri: "https://gitlab.example.com/users/auth/azure_oauth2/callback"
      }
    }
  }
]
gitlab_rails['omniauth_providers'] = [
  {
    name: "azure_activedirectory_v2",
    label: "Azure OIDC", # optional label for login button, defaults to "Openid Connect"
    args: {
      name: "azure_activedirectory_v2",
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com/<YOUR-TENANT-ID>/v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "oid",
      send_scope_to_token_endpoint: "false",
      client_options: {
        identifier: "<YOUR APP CLIENT ID>",
        secret: "<YOUR APP CLIENT SECRET>",
        redirect_uri: "https://gitlab.example.com/users/auth/azure_activedirectory_v2/callback"
      }
    }
  }
]

对于 Helm 安装:

在 YAML 文件(例如 provider.yaml)中添加提供程序配置

{
  "name": "azure_oauth2",
  "args": {
    "name": "azure_oauth2",
    "strategy_class": "OmniAuth::Strategies::OpenIDConnect",
    "scope": [
      "openid",
      "profile",
      "email"
    ],
    "response_type": "code",
    "issuer": "https://login.microsoftonline.com/<YOUR-TENANT-ID>/v2.0",
    "client_auth_method": "query",
    "discovery": true,
    "uid_field": "sub",
    "send_scope_to_token_endpoint": false,
    "client_options": {
      "identifier": "<YOUR APP CLIENT ID>",
      "secret": "<YOUR APP CLIENT SECRET>",
      "redirect_uri": "https://gitlab.example.com/users/auth/azure_oauth2/callback"
    }
  }
}
{
  "name": "azure_activedirectory_v2",
  "args": {
    "name": "azure_activedirectory_v2",
    "strategy_class": "OmniAuth::Strategies::OpenIDConnect",
    "scope": [
      "openid",
      "profile",
      "email"
    ],
    "response_type": "code",
    "issuer": "https://login.microsoftonline.com/<YOUR-TENANT-ID>/v2.0",
    "client_auth_method": "query",
    "discovery": true,
    "uid_field": "sub",
    "send_scope_to_token_endpoint": false,
    "client_options": {
      "identifier": "<YOUR APP CLIENT ID>",
      "secret": "<YOUR APP CLIENT SECRET>",
      "redirect_uri": "https://gitlab.example.com/users/auth/activedirectory_v2/callback"
    }
  }
}

当您作为升级到 GitLab 17.0 或更高版本的一部分,从 azure_oauth2 迁移到 omniauth_openid_connect 时,为您的组织设置的 sub 声明值可能会有所不同。azure_oauth2 使用 Microsoft V1 端点,而 azure_activedirectory_v2omniauth_openid_connect 都使用具有通用 sub 值的 Microsoft V2 端点。

  • 对于在 Entra ID 中有电子邮件地址的用户,为了允许回退到电子邮件地址并更新用户身份, 请配置以下内容:

  • 在 Linux 包安装中,omniauth_auto_link_user

  • 在 Helm 安装中,autoLinkUser

  • 对于没有电子邮件地址的用户,管理员必须采取以下操作之一:

  • 设置另一种身份验证方法或启用使用 GitLab 用户名和密码登录。然后用户可以登录并通过其个人资料手动链接其 Azure 身份。

  • 将 OpenID Connect 实现为与现有 azure_oauth2 并行的新提供程序,以便用户可以通过 OAuth2 登录,并链接其 OpenID Connect 身份(类似于前一种方法)。只要启用了 auto_link_user,此方法也适用于有电子邮件地址的用户。

  • 手动更新 extern_uid。为此,使用 API 或 Rails 控制台 为每个用户更新 extern_uid。 如果实例已经升级到 17.0 或更高版本,并且用户已尝试登录,则可能需要此方法。

如果在配置 GitLab 帐户时 email 声明缺失或为空,azure_oauth2 可能已使用 Entra ID 的 upn 声明作为电子邮件地址。

配置 Microsoft Azure Active Directory B2C

GitLab 需要特殊配置才能与 Azure Active Directory B2C 一起使用。要开始,请登录 Azure Portal。 对于您的应用程序,您需要从 Azure 获取以下信息:

  • 租户 ID。您可能已经有一个。有关更多信息,请查看 Microsoft Azure 租户 文档。

  • 客户端 ID 和客户端密钥。按照 Microsoft 教程 文档中的说明获取 您的应用程序的客户端 ID 和客户端密钥。

  • 用户流或策略名称。按照 Microsoft 教程 中的说明操作。

配置应用程序:

  1. 设置应用程序 Redirect URI。例如,如果您的 GitLab 域是 gitlab.example.com, 将应用程序 Redirect URI 设置为 https://gitlab.example.com/users/auth/openid_connect/callback

  2. 启用 ID 令牌

  3. 向应用程序添加以下 API 权限:

  • openid

  • offline_access

配置自定义策略

Azure B2C 提供了两种定义用户登录业务逻辑的方式

需要自定义策略,因为标准的 Azure B2C 用户流 不发送 OpenID email 声明。 因此,标准用户流不适用于 allow_single_sign_onauto_link_user 参数。 使用标准的 Azure B2C 策略,GitLab 无法创建新帐户或 链接到具有电子邮件地址的现有帐户。

首先,创建自定义策略

Microsoft 说明在 自定义策略入门包 中使用 SocialAndLocalAccounts, 但 LocalAccounts 对本地 Active Directory 帐户进行身份验证。在您上传策略之前,请执行以下操作:

  1. 要导出 email 声明,请修改 SignUpOrSignin.xml。替换以下行:
   <OutputClaim ClaimTypeReferenceId="email" />

为:

   <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
  1. 为了使 OIDC 发现与 B2C 一起工作,请配置具有与 OIDC 规范 兼容的颁发者的策略。 请参阅 令牌兼容性设置。 在 TrustFrameworkBase.xml 中的 JwtIssuer 下,将 IssuanceClaimPattern 设置为 AuthorityWithTfp
   <ClaimsProvider>
     <DisplayName>Token Issuer</DisplayName>
     <TechnicalProfiles>
       <TechnicalProfile Id="JwtIssuer">
         <DisplayName>JWT Issuer</DisplayName>
         <Protocol Name="None" />
         <OutputTokenFormat>JWT</OutputTokenFormat>
         <Metadata>
           <Item Key="IssuanceClaimPattern">AuthorityWithTfp</Item>
           ...
  1. 上传策略。如果您正在更新现有策略,请覆盖 现有文件。

  2. 要确定颁发者 URL,请使用登录策略。颁发者 URL 的格式为:

   https://<YOUR-DOMAIN>/tfp/<YOUR-TENANT-ID>/<YOUR-SIGN-IN-POLICY-NAME>/v2.0/

策略名称在 URL 中为小写。例如,B2C_1A_signup_signin 策略显示为 b2c_1a_signup_sigin

确保包含末尾的正斜杠。

  1. 验证 OIDC 发现 URL 和颁发者 URL 的操作,并将 .well-known/openid-configuration 附加到颁发者 URL:
   https://<YOUR-DOMAIN>/tfp/<YOUR-TENANT-ID>/<YOUR-SIGN-IN-POLICY-NAME>/v2.0/.well-known/openid-configuration

例如,如果 domainexample.b2clogin.com 且租户 ID 是 fc40c736-476c-4da1-b489-ee48cee84386,您可以使用 curljq 提取颁发者:

   $ curl --silent "https://example.b2clogin.com/tfp/fc40c736-476c-4da1-b489-ee48cee84386/b2c_1a_signup_signin/v2.0/.well-known/openid-configuration" | jq .issuer
   "https://example.b2clogin.com/tfp/fc40c736-476c-4da1-b489-ee48cee84386/b2c_1a_signup_signin/v2.0/"
  1. 使用用于 signup_signin 的自定义策略配置颁发者 URL。例如,这是 Linux 包安装中 b2c_1a_signup_signin 的自定义策略配置:
   gitlab_rails['omniauth_providers'] = [
   {
     name: "openid_connect", # do not change this parameter
     label: "Azure B2C OIDC", # optional label for login button, defaults to "Openid Connect"
     args: {
       name: "openid_connect",
       scope: ["openid"],
       response_mode: "query",
       response_type: "id_token",
       issuer:  "https://<YOUR-DOMAIN>/tfp/<YOUR-TENANT-ID>/b2c_1a_signup_signin/v2.0/",
       client_auth_method: "query",
       discovery: true,
       send_scope_to_token_endpoint: true,
       pkce: true,
       client_options: {
         identifier: "<YOUR APP CLIENT ID>",
         secret: "<YOUR APP CLIENT SECRET>",
         redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
       }
     }
   }]

Azure B2C 故障排除

  • 确保 yourtenant.onmicrosoft.comProxyIdentityExperienceFrameworkAppIdIdentityExperienceFrameworkAppId 的所有出现都与您的 B2C 租户主机名和 XML 策略文件中的相应客户端 ID 匹配。

  • https://jwt.ms 添加为应用程序的重定向 URI,并使用 自定义策略测试器。 确保负载包含与用户电子邮件访问权限匹配的 email

  • 启用自定义策略后,用户在尝试登录后可能会看到 无效的用户名或密码。 这可能是 IdentityExperienceFramework 应用程序的配置问题。请参阅 此 Microsoft 评论,该评论建议您检查应用程序清单 是否包含这些设置:

  • "accessTokenAcceptedVersion": null

  • "signInAudience": "AzureADMyOrg"

此配置对应于创建 IdentityExperienceFramework 应用时使用的 Supported account types 设置。

配置 Keycloak

GitLab 可以与使用 HTTPS 的 OpenID 提供商配合使用。虽然您可以设置使用 HTTP 的 Keycloak 服务器,但 GitLab 只能与使用 HTTPS 的 Keycloak 服务器通信。

配置 Keycloak 使用公钥加密算法(例如,RSA256 或 RSA512)而不是对称密钥加密算法(例如,HS256 或 HS358)来签名令牌。公钥加密算法的优点是:

  • 更容易配置。

  • 更安全,因为泄露私钥会带来严重的安全后果。

  1. 打开 Keycloak 管理控制台。

  2. 选择 Realm Settings > Tokens > Default Signature Algorithm

  3. 配置签名算法。

Linux 包安装的示例配置块:

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect", # 请勿更改此参数
    label: "Keycloak", # 登录按钮的可选标签,默认为 "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://keycloak.example.com/realms/myrealm",
      client_auth_method: "query",
      discovery: true,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "<YOUR CLIENT ID>",
        secret: "<YOUR CLIENT SECRET>",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
      }
    }
  }
]

使用对称密钥算法配置 Keycloak

以下说明是为了完整性而包含的,但仅在绝对必要时才使用对称密钥加密。

要使用对称密钥加密:

  1. 从 Keycloak 数据库中提取密钥。Keycloak 不会在 Web 界面中显示此值。在 Web 界面中看到的客户端密钥是 OAuth 2.0 客户端密钥,与用于签名 JSON Web 令牌的密钥不同。

例如,如果您使用 PostgreSQL 作为 Keycloak 的后端数据库:

  • 登录到数据库控制台。

  • 运行以下 SQL 查询以提取密钥:

     $ psql -U keycloak
     psql (13.3 (Debian 13.3-1.pgdg100+1))
     Type "help" for help.

keycloak=# SELECT c.name, value FROM component_config CC INNER JOIN component C ON(CC.component_id = C.id) WHERE C.realm_id = 'master' and provider_id = 'hmac-generated' AND CC.name = 'secret';
     -[ RECORD 1 ]---------------------------------------------------------------------------------
     name  | hmac-generated
     value | lo6cqjD6Ika8pk7qc3fpFx9ysrhf7E62-sqGc8drp3XW-wr93zru8PFsQokHZZuJJbaUXvmiOftCZM3C4KW3-g
     -[ RECORD 2 ]---------------------------------------------------------------------------------
     name  | fallback-HS384
     value | UfVqmIs--U61UYsRH-NYBH3_mlluLONpg_zN7CXEwkJcO9xdRNlzZfmfDLPtf2xSTMvqu08R2VhLr-8G-oZ47A
     ```

在此示例中,有两个私钥:一个用于 HS256 (`hmac-generated`),另一个用于 HS384 (`fallback-HS384`)。我们使用第一个 `value` 来配置 GitLab

1.  `value` 转换为标准 base64。如 [**Invalid signature with HS256 token** 帖子](https://keycloak.discourse.group/t/invalid-signature-with-hs256-token/3228/9) 中所讨论,
   `value` 是使用 RFC 4648  [**Base 64 Encoding with URL and Filename Safe Alphabet** 部分](https://datatracker.ietf.org/doc/html/rfc4648#section-5) 编码的。
   必须将其转换为 [RFC 2045 中定义的标准 base64](https://datatracker.ietf.org/doc/html/rfc2045)
   以下 Ruby 脚本可以完成此操作:

```ruby
   require 'base64'

value = "lo6cqjD6Ika8pk7qc3fpFx9ysrhf7E62-sqGc8drp3XW-wr93zru8PFsQokHZZuJJbaUXvmiOftCZM3C4KW3-g"
   Base64.encode64(Base64.urlsafe_decode64(value))

这将产生以下值:

   lo6cqjD6Ika8pk7qc3fpFx9ysrhf7E62+sqGc8drp3XW+wr93zru8PFsQokH\nZZuJJbaUXvmiOftCZM3C4KW3+g==\n
  1. jwt_secret_base64 中指定此 base64 编码的密钥。例如:
   gitlab_rails['omniauth_providers'] = [
     {
       name: "openid_connect", # 请勿更改此参数
       label: "Keycloak", # 登录按钮的可选标签,默认为 "Openid Connect"
       args: {
         name: "openid_connect",
         scope: ["openid", "profile", "email"],
         response_type: "code",
         issuer:  "https://keycloak.example.com/auth/realms/myrealm",
         client_auth_method: "query",
         discovery: true,
         uid_field: "preferred_username",
         jwt_secret_base64: "<YOUR BASE64-ENCODED SECRET>",
         pkce: true,
         client_options: {
           identifier: "<YOUR CLIENT ID>",
           secret: "<YOUR CLIENT SECRET>",
           redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
         }
       }
     }
   ]

如果您看到 JSON::JWS::VerificationFailed 错误,说明您指定的密钥不正确。

Casdoor

GitLab 可以与使用 HTTPS 的 OpenID 提供商配合使用。使用 HTTPS 通过 OpenID 与 Casdoor 连接到 GitLab。

对于您的应用程序,在 Casdoor 上完成以下步骤:

  1. 获取客户端 ID 和客户端密钥。

  2. 添加您的 GitLab 重定向 URL。例如,如果您的 GitLab 域是 gitlab.example.com,请确保 Casdoor 应用具有以下 Redirect URIhttps://gitlab.example.com/users/auth/openid_connect/callback

更多详情请参阅 Casdoor 文档

Linux 包安装的示例配置(文件路径:/etc/gitlab/gitlab.rb):

gitlab_rails['omniauth_providers'] = [
    {
        name: "openid_connect", # 请勿更改此参数
        label: "Casdoor", # 登录按钮的可选标签,默认为 "Openid Connect"
        args: {
            name: "openid_connect",
            scope: ["openid", "profile", "email"],
            response_type: "code",
            issuer:  "https://<CASDOOR_HOSTNAME>",
            client_auth_method: "query",
            discovery: true,
            uid_field: "sub",
            client_options: {
                identifier: "<YOUR CLIENT ID>",
                secret: "<YOUR CLIENT SECRET>",
                redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
            }
        }
    }
]

自行编译安装的示例配置(文件路径:config/gitlab.yml):


- { name: 'openid_connect', # 请勿更改此参数
      label: 'Casdoor', # 登录按钮的可选标签,默认为 "Openid Connect"
      args: {
        name: 'openid_connect',
        scope: ['openid', 'profile', 'email'],
        response_type: 'code',
        issuer: 'https://<CASDOOR_HOSTNAME>',
        discovery: true,
        client_auth_method: 'query',
        uid_field: 'sub',
        client_options: {
          identifier: '<YOUR CLIENT ID>',
          secret: '<YOUR CLIENT SECRET>',
          redirect_uri: 'https://gitlab.example.com/users/auth/openid_connect/callback'
        }
      }
    }

配置多个 OpenID Connect 提供商

您可以配置应用程序使用多个 OpenID Connect (OIDC) 提供商。通过在配置文件中明确设置 strategy_class 来实现此操作。

在以下任一情况下,您应该执行此操作:

以下示例配置显示了如何提供不同级别的身份验证,一个选项使用 2FA,另一个不使用 2FA。

对于 Linux 包安装:

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect",
    label: "Provider name", # 登录按钮的可选标签,默认为 "Openid Connect"
    icon: "<custom_provider_icon>",
    args: {
      name: "openid_connect",
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid","profile","email"],
      response_type: "code",
      issuer: "<your_oidc_url>",
      discovery: true,
      client_auth_method: "query",
      uid_field: "<uid_field>",
      send_scope_to_token_endpoint: "false",
      pkce: true,
      client_options: {
        identifier: "<your_oidc_client_id>",
        secret: "<your_oidc_client_secret>",
        redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback"
      }
    }
  },
  {
    name: "openid_connect_2fa",
    label: "Provider name 2FA", # 登录按钮的可选标签,默认为 "Openid Connect"
    icon: "<custom_provider_icon>",
    args: {
      name: "openid_connect_2fa",
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid","profile","email"],
      response_type: "code",
      issuer: "<your_oidc_url>",
      discovery: true,
      client_auth_method: "query",
      uid_field: "<uid_field>",
      send_scope_to_token_endpoint: "false",
      pkce: true,
      client_options: {
        identifier: "<your_oidc_client_id>",
        secret: "<your_oidc_client_secret>",
        redirect_uri: "<your_gitlab_url>/users/auth/openid_connect_2fa/callback"
      }
    }
  }
]

对于自行编译安装:


- { name: 'openid_connect',
      label: 'Provider name', # 登录按钮的可选标签,默认为"Openid Connect"
      icon: '<custom_provider_icon>',
      args: {
        name: 'openid_connect',
        strategy_class: "OmniAuth::Strategies::OpenIDConnect",
        scope: ['openid', 'profile', 'email'],
        response_type: 'code',
        issuer: '<your_oidc_url>',
        discovery: true,
        client_auth_method: 'query',
        uid_field: '<uid_field>',
        send_scope_to_token_endpoint: false,
        pkce: true,
        client_options: {
          identifier: '<your_oidc_client_id>',
          secret: '<your_oidc_client_secret>',
          redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback'
        }
      }
    }

- { name: 'openid_connect_2fa',
      label: 'Provider name 2FA', # 登录按钮的可选标签,默认为"Openid Connect"
      icon: '<custom_provider_icon>',
      args: {
        name: 'openid_connect_2fa',
        strategy_class: "OmniAuth::Strategies::OpenIDConnect",
        scope: ['openid', 'profile', 'email'],
        response_type: 'code',
        issuer: '<your_oidc_url>',
        discovery: true,
        client_auth_method: 'query',
        uid_field: '<uid_field>',
        send_scope_to_token_endpoint: false,
        pkce: true,
        client_options: {
          identifier: '<your_oidc_client_id>',
          secret: '<your_oidc_client_secret>',
          redirect_uri: '<your_gitlab_url>/users/auth/openid_connect_2fa/callback'
        }
      }
    }

在这个用例中,您可能希望根据企业目录中已有的已知标识符,在不同提供商之间同步 extern_uid

为此,您需要设置 uid_field。以下示例代码展示了如何操作:

def sync_missing_provider(self, user: User, extern_uid: str)
  existing_identities = []
  for identity in user.identities:
      existing_identities.append(identity.get("provider"))

local_extern_uid = extern_uid.lower()
  for provider in ("openid_connect_2fa", "openid_connect"):
      identity = [
          identity
          for identity in user.identities
          if identity.get("provider") == provider
          and identity.get("extern_uid").lower() != local_extern_uid
      ]
      if provider not in existing_identities or identity:
          if identity and identity[0].get("extern_uid") != "":
              logger.error(f"Found different identity for provider {provider} for user {user.id}")
              continue
          else:
              logger.info(f"Add identity 'provider': {provider}, 'extern_uid': {extern_uid} for user {user.id}")
              user.provider = provider
              user.extern_uid = extern_uid
              user = self.save_user(user)
  return user

更多信息,请参阅 GitLab API 用户方法文档

基于 OIDC 组成员资格配置用户

  • Tier: Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

您可以配置 OIDC 组成员资格以:

  • 要求用户是特定组的成员。

  • 根据组成员资格为用户分配外部、管理员或 审计员角色。

GitLab 会在每次登录时检查这些组,并根据需要更新用户属性。 此功能不能让您自动将用户添加到 GitLab 中。

必需组

您的身份提供商(IdP)必须在 OIDC 响应中将组信息传递给 GitLab。要使用此响应要求用户成为特定组的成员,请配置 GitLab 以识别:

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。

  • 登录需要哪些组成员资格,使用 required_groups 设置。

如果您未设置 required_groups 或将该设置留空,则任何通过 OIDC 由 IdP 认证的用户都可以使用 GitLab。

  1. 编辑 /etc/gitlab/gitlab.rb
   gitlab_rails['omniauth_providers'] = [
     {
       name: "openid_connect",
       label: "Provider name",
       args: {
         name: "openid_connect",
         scope: ["openid","profile","email"],
         response_type: "code",
         issuer: "<your_oidc_url>",
         discovery: true,
         client_auth_method: "query",
         uid_field: "<uid_field>",
         client_options: {
           identifier: "<your_oidc_client_id>",
           secret: "<your_oidc_client_secret>",
           redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback",
           gitlab: {
             groups_attribute: "groups",
             required_groups: ["Developer"]
           }
         }
       }
     }
   ]
  1. 保存文件并重新配置 GitLab 以使更改生效。
  1. 编辑 /home/git/gitlab/config/gitlab.yml
   production: &base
     omniauth:
       providers:

- { name: 'openid_connect',
            label: 'Provider name',
         args: {
           name: 'openid_connect',
           scope: ['openid','profile','email'],
           response_type: 'code',
           issuer: '<your_oidc_url>',
           discovery: true,
           client_auth_method: 'query',
           uid_field: '<uid_field>',
           client_options: {
             identifier: '<your_oidc_client_id>',
             secret: '<your_oidc_client_secret>',
             redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback',
             gitlab: {
               groups_attribute: "groups",
               required_groups: ["Developer"]
             }
           }
         }
       }
  1. 保存文件并重新配置 GitLab 以使更改生效。

外部组

您的 IdP 必须在 OIDC 响应中将组信息传递给 GitLab。要使用此响应根据组成员资格将用户标识为外部用户,请配置 GitLab 以识别:

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。

  • 哪些组成员资格应将用户标识为外部用户,使用 external_groups 设置。

  1. 编辑 /etc/gitlab/gitlab.rb
   gitlab_rails['omniauth_providers'] = [
     {
       name: "openid_connect",
       label: "Provider name",
       args: {
         name: "openid_connect",
         scope: ["openid","profile","email"],
         response_type: "code",
         issuer: "<your_oidc_url>",
         discovery: true,
         client_auth_method: "query",
         uid_field: "<uid_field>",
         client_options: {
           identifier: "<your_oidc_client_id>",
           secret: "<your_oidc_client_secret>",
           redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback",
           gitlab: {
             groups_attribute: "groups",
             external_groups: ["Freelancer"]
           }
         }
       }
     }
   ]
  1. 保存文件并重新配置 GitLab 以使更改生效。
  1. 编辑 /home/git/gitlab/config/gitlab.yml
   production: &base
     omniauth:
       providers:

- { name: 'openid_connect',
            label: 'Provider name',
         args: {
           name: 'openid_connect',
           scope: ['openid','profile','email'],
           response_type: 'code',
           issuer: '<your_oidc_url>',
           discovery: true,
           client_auth_method: 'query',
           uid_field: '<uid_field>',
           client_options: {
             identifier: '<your_oidc_client_id>',
             secret: '<your_oidc_client_secret>',
             redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback',
             gitlab: {
               groups_attribute: "groups",
               external_groups: ["Freelancer"]
             }
           }
         }
       }
  1. 保存文件并重新配置 GitLab 以使更改生效。

审计员组

  • Tier: Premium, Ultimate
  • Offering: GitLab Self-Managed

您的 IdP 必须在 OIDC 响应中将组信息传递给 GitLab。要使用此响应根据组成员资格将用户分配为审计员,请配置 GitLab 以识别:

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。

  • 哪些组成员资格授予用户审计员访问权限,使用 auditor_groups 设置。

  1. 编辑 /etc/gitlab/gitlab.rb
   gitlab_rails['omniauth_providers'] = [
     {
       name: "openid_connect",
       label: "Provider name",
       args: {
         name: "openid_connect",
         scope: ["openid","profile","email","groups"],
         response_type: "code",
         issuer: "<your_oidc_url>",
         discovery: true,
         client_auth_method: "query",
         uid_field: "<uid_field>",
         client_options: {
           identifier: "<your_oidc_client_id>",
           secret: "<your_oidc_client_secret>",
           redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback",
           gitlab: {
             groups_attribute: "groups",
             auditor_groups: ["Auditor"]
           }
         }
       }
     }
   ]
  1. 保存文件并重新配置 GitLab 以使更改生效。
  1. 编辑 /home/git/gitlab/config/gitlab.yml
   production: &base
     omniauth:
       providers:

- { name: 'openid_connect',
            label: 'Provider name',
         args: {
           name: 'openid_connect',
           scope: ['openid','profile','email','groups'],
           response_type: 'code',
           issuer: '<your_oidc_url>',
           discovery: true,
           client_auth_method: 'query',
           uid_field: '<uid_field>',
           client_options: {
             identifier: '<your_oidc_client_id>',
             secret: '<your_oidc_client_secret>',
             redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback',
             gitlab: {
               groups_attribute: "groups",
               auditor_groups: ["Auditor"]
             }
           }
         }
       }
  1. 保存文件并重新配置 GitLab 以使更改生效。

管理员组

您的 IdP 必须在 OIDC 响应中将组信息传递给 GitLab。要使用此响应 根据组成员身份将用户分配为管理员,请配置 GitLab 来识别:

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。

  • 哪些组成员身份授予用户管理员访问权限,使用 admin_groups 设置。

  1. 编辑 /etc/gitlab/gitlab.rb
   gitlab_rails['omniauth_providers'] = [
     {
       name: "openid_connect",
       label: "Provider name",
       args: {
         name: "openid_connect",
         scope: ["openid","profile","email"],
         response_type: "code",
         issuer: "<your_oidc_url>",
         discovery: true,
         client_auth_method: "query",
         uid_field: "<uid_field>",
         client_options: {
           identifier: "<your_oidc_client_id>",
           secret: "<your_oidc_client_secret>",
           redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback",
           gitlab: {
             groups_attribute: "groups",
             admin_groups: ["Admin"]
           }
         }
       }
     }
   ]
  1. 保存文件并重新配置 GitLab 以使更改生效。
  1. 编辑 /home/git/gitlab/config/gitlab.yml
   production: &base
     omniauth:
       providers:

- { name: 'openid_connect',
            label: 'Provider name',
         args: {
           name: 'openid_connect',
           scope: ['openid','profile','email'],
           response_type: 'code',
           issuer: '<your_oidc_url>',
           discovery: true,
           client_auth_method: 'query',
           uid_field: '<uid_field>',
           client_options: {
             identifier: '<your_oidc_client_id>',
             secret: '<your_oidc_client_secret>',
             redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback',
             gitlab: {
               groups_attribute: "groups",
               admin_groups: ["Admin"]
             }
           }
         }
       }
  1. 保存文件并重新配置 GitLab 以使更改生效。

配置 ID 令牌的自定义持续时间

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab Self-Managed

默认情况下,GitLab ID 令牌在 120 秒后过期。

要为您的 ID 令牌配置自定义持续时间:

  1. 编辑 /etc/gitlab/gitlab.rb
   gitlab_rails['oidc_provider_openid_id_token_expire_in_seconds'] = 3600
  1. 保存文件并重新配置 GitLab 以使更改生效。
  1. 编辑 /home/git/gitlab/config/gitlab.yml
   production: &base
     oidc_provider:
      openid_id_token_expire_in_seconds: 3600
  1. 保存文件并重新配置 GitLab 以使更改生效。

管理员模式的升级认证

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab Self-Managed
  • Status: Experiment

The availability of this feature is controlled by a feature flag. For more information, see the history. This feature is available for testing, but not ready for production use.

在某些情况下,默认认证方法不足以保护关键资源或 高风险操作。升级认证为特权操作或敏感操作(如访问管理员区域)添加了额外的认证层。

使用升级认证,用户必须提供额外的凭据才能访问 某些功能或执行特定操作。这些额外方法可以包括 双因素认证(2FA)、生物识别认证或一次性密码(OTP)等方法。

OIDC 标准包括认证上下文类引用(ACR)。ACR 概念 有助于为不同场景(如管理员模式)配置和实施升级认证。

此功能是一个实验性功能,可能会在没有通知的情况下更改。此功能尚未准备好用于生产环境。如果您想使用此功能,应该先在生产环境之外进行测试。

为管理员模式启用升级认证

要为管理员模式启用升级认证:

  1. 编辑您的 GitLab 配置文件(gitlab.yml/etc/gitlab/gitlab.rb)以启用 特定 OmniAuth 提供程序的升级认证。
   production: &base
     omniauth:
       providers:

- { name: 'openid_connect',
           label: 'Provider name',
           args: {
             name: 'openid_connect',
             # ...
             allow_authorize_params: ["claims"], # 将此与 `step_up_auth => admin_mode => params` 中定义的参数匹配
           },
           step_up_auth: {
             admin_mode: {
               # `id_token` 字段定义必须包含在令牌中的声明。
               # 您可以在 `required` 或 `included` 字段中的一个或两个字段中指定声明。
               # 令牌必须包含您在这些字段中定义的每个声明的匹配值。
               id_token: {
                 # `required` 字段定义必须包含在 ID 令牌中的键值对。
                 # 值必须与定义的完全匹配。
                 # 在此示例中,'acr'(认证上下文类引用)声明
                 # 必须具有值 'gold' 才能通过升级认证挑战。
                 # 这确保了特定的认证保证级别。
                 required: {
                   acr: 'gold'
                 },
                 # `included` 字段也定义必须包含在 ID 令牌中的键值对。
                 # 可以在数组中定义多个接受的值。如果不使用数组,则值必须完全匹配。
                 # 在此示例中,'amr'(认证方法引用)声明
                 # 必须具有 'mfa' 或 'fpt' 的值才能通过升级认证挑战。
                 # 这对于用户必须提供额外认证因素的场景很有用。
                 included: {
                   amr: ['mfa', 'fpt']
                 },
               },
               # `params` 字段定义在认证过程中发送的任何额外参数。
               # 在此示例中,`claims` 参数被添加到授权请求中,并指示
               # 身份提供程序在 ID 令牌中包含值为 'gold' 的 'acr' 声明。
               # 'essential: true' 表示此声明是成功认证所必需的。
               params: {
                 claims: {
                   id_token: {
                     acr: {
                       essential: true,
                       values: ['gold']
                     }
                   }
                 }
               }
             },
           }
         }
  1. 保存配置文件并重启 GitLab 以使更改生效。

尽管 OIDC 是标准化的,但不同的身份提供商 (IdP) 可能有独特的要求。 params 设置允许使用一个灵活的哈希来定义渐进式认证所需的参数。 这些值可能因每个 IdP 的具体要求而异。

使用 Keycloak 为管理员模式启用渐进式认证

Keycloak 通过定义认证级别和自定义浏览器登录流程来支持渐进式认证。

要使用 Keycloak 为 GitLab 的管理员模式配置渐进式认证:

  1. 在 GitLab 中配置 Keycloak

  2. 按照 Keycloak 文档中的步骤,在 Keycloak 中创建一个带渐进式认证的浏览器登录流程

  3. 编辑您的 GitLab 配置文件(gitlab.yml/etc/gitlab/gitlab.rb),在 Keycloak OIDC 提供商配置中启用渐进式认证。

Keycloak 定义了两种不同的认证级别:silvergold。以下示例使用 gold 来代表更高的安全级别。

   production: &base
     omniauth:
       providers:

- { name: 'openid_connect',
           label: 'Keycloak',
           args: {
             name: 'openid_connect',
             # ...
             allow_authorize_params: ["claims"] # Match this to the parameters defined in `step_up_auth => admin_mode => params`
           },
           step_up_auth: {
             admin_mode: {
               id_token: {
                 # In this example, the 'acr' claim must have the value 'gold' that is also defined in the Keycloak documentation.
                 required: {
                   acr: 'gold'
                 }
               },
               params: {
                 claims: { id_token: { acr: { essential: true, values: ['gold'] } } }
               }
             },
           }
         }
  1. 保存配置文件并重启 GitLab 以使更改生效。

使用 Microsoft Entra ID 为管理员模式启用渐进式认证

Microsoft Entra ID (以前称为 Azure Active Directory) 通过条件访问身份验证上下文支持渐进式认证。 您应与 Microsoft Entra ID 管理员合作,以定义正确的配置。

请注意以下几点:

  • 身份验证上下文 ID 仅通过 acrs 声明请求,而不是通过其他身份提供商使用的 ID 令牌声明 acr

  • 身份验证上下文 ID 使用从 c1c99 的固定值,每个值代表一个具有条件访问策略的特定身份验证上下文。

  • 默认情况下,Microsoft Entra ID 不会在 ID 令牌中包含 acrs 声明。要启用此功能,您必须配置可选声明

  • 当渐进式认证成功后,响应会将 acrs 声明作为字符串的 JSON 数组返回。例如:acrs: ["c1", "c2", "c3"]

要使用 Microsoft Entra ID 为 GitLab 的管理员模式配置渐进式认证:

  1. 在 GitLab 中配置 Microsoft Entra ID

  2. 按照 Microsoft Entra ID 文档中的步骤,在 Microsoft Entra ID 中定义条件访问身份验证上下文

  3. 在 Microsoft Entra ID 中,定义要包含在 ID 令牌中的可选声明 acrs

  4. 编辑您的 GitLab 配置文件(gitlab.yml/etc/gitlab/gitlab.rb),在 Microsoft Entra ID 提供商配置中启用渐进式认证:

   production: &base
     omniauth:
       providers:

- { name: 'openid_connect',
         label: 'Azure OIDC',
         args: {
           name: 'openid_connect',
           # ...
           allow_authorize_params: ["claims"] # Match this to the parameters defined in `step_up_auth => admin_mode => params`
         },
         step_up_auth: {
           admin_mode: {
             id_token: {
               # In this example, the Microsoft Entra ID administrators have definded `c20`
               # as the authentication context ID with the desired security level and
               # an optional claim `acrs` to be included in the ID token.
               # The `included` field declares that the id token claim `acrs` must include the value `c20`.
               included: {
                 acrs: ["c20"],
               },
             },
             params: {
               claims: {
                 id_token: {
                   acrs: { essential: true, value: 'c20' }
                 }
               },
             }
           },
         }
       }
  1. 保存配置文件并重启 GitLab 以使更改生效。

故障排除

  1. 确保 discovery 设置为 true。如果将其设置为 false,则必须指定使 OpenID 正常工作所需的所有 URL 和密钥。

  2. 检查您的系统时钟,确保时间已正确同步。

  3. OmniAuth OpenID Connect 文档 中所述,请确保 issuer 与 Discovery URL 的基础 URL 相对应。例如,对于 URL https://accounts.google.com/.well-known/openid-configuration,其 issuerhttps://accounts.google.com

  4. 如果未定义 client_auth_method 或将其设置为 basic,OpenID Connect 客户端将使用 HTTP 基本身份验证来发送 OAuth 2.0 访问令牌。如果在获取 userinfo 端点时看到 401 错误,请检查您的 OpenID Web 服务器配置。例如,对于 oauth2-server-php,您可能需要向 Apache 添加一个配置参数

  5. 仅限渐进式认证:确保在 step_up_auth => admin_mode => params 中定义的任何参数,也同样在 args => allow_authorize_params 中进行了定义。这包括用于重定向到 IdP 授权端点的请求查询参数中的参数。