使用 OpenID Connect 作为认证提供者

您可以使用极狐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
    
  2. 配置通用设置以添加 openid_connect 作为单点登录提供者。这为没有现有极狐GitLab 帐户的用户启用即时账户配置。

  3. 添加提供者配置。

    对于 Linux 软件包安装:

    gitlab_rails['omniauth_providers'] = [
      {
        name: "openid_connect", # do not change this parameter
        label: "Provider name", # optional label for login button, defaults to "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', # do not change this parameter
          label: 'Provider name', # optional label for login button, defaults to "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'
            }
          }
        }
    
  4. 对于提供者配置,更改提供者的值以匹配您的 OpenID Connect 客户端设置。使用以下作为指南:

    • <your_oidc_label> 是登录页面上显示的标签。
    • <custom_provider_icon> (可选)是登录页面上显示的图标。极狐GitLab 内置了主要社交登录平台的图标,但您可以通过指定此参数来覆盖这些图标。极狐GitLab 接受本地路径和绝对 URL。
    • <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 (可选):启用 代码交换的证明密钥。可用于极狐GitLab 15.9。
    • client_options 是 OpenID Connect 客户端特定选项。具体来说:
      • identifier 是在 OpenID Connect 服务提供者中配置的客户端标识符。
      • secret 是在 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。
  5. 保存配置文件。
  6. 要使更改生效,如果您:

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

示例配置

以下配置说明如何在使用 Linux 软件包安装时与不同提供者一起设置 OpenID。

配置 Microsoft Azure

Microsoft Azure 的 OpenID Connect (OIDC) 协议使用 Microsoft identity platform (v2) endpoints。要开始,请登录 Azure Portal。对于您的应用,您需要以下信息:

  • 一个租户 ID。您可能已经有一个。
  • 一个客户端 ID 和一个客户端秘密。获取您的应用的租户 ID、客户端 ID 和客户端秘密。

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 Entra 自定义签名密钥

如果您的应用程序有自定义签名密钥,因为您使用了 SAML claims-mapping feature,则必须以以下方式配置 OpenID 提供者:

  • 通过省略 args.discovery 或将其设置为 false 来禁用 OpenID Connect 发现。
  • 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 会引发该错误。

迁移到通用 OpenID Connect 配置

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

首先,设置 uid_fielduid_field 和您可以选择作为 uid_fieldsub 声明因提供者而异。未设置 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 软件包安装,请按以下方式更新配置:

::Tabs

:::TabTitle Azure OAuth 2.0

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"
      }
    }
  }
]

:::TabTitle Azure Active Directory v2

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"
      }
    }
  }
]

::EndTabs

对于 Helm 安装:

在 YAML 文件(例如,provider.yaml)中添加提供者的配置

::Tabs

:::TabTitle Azure OAuth 2.0

{
  "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"
    }
  }
}

:::TabTitle Azure Active Directory v2

{
  "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"
    }
  }
}

::EndTabs

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

  • 对于在 Entra ID 中有电子邮件地址的用户,为了允许回退到电子邮件地址并更新用户身份,请配置以下内容:
  • 对于没有电子邮件地址的用户,管理员必须采取以下行动之一:

    • 设置另一种认证方法或启用使用极狐GitLab 用户名和密码登录。然后,用户可以登录并使用其个人资料手动链接其 Azure 身份。
    • 实施 OpenID Connect 作为现有 azure_oauth2 的新提供者,以便用户可以通过 OAuth2 登录,并链接其 OpenID Connect 身份(类似于前一种方法)。此方法也适用于有电子邮件地址的用户,只要启用了 auto_link_user
    • 手动更新 extern_uid。为此,请使用 API 或 Rails 控制台 更新每个用户的 extern_uid。如果实例已升级到 17.0 或更高版本,且用户已尝试登录,则可能需要此方法。
note如果在配置极狐GitLab 帐户时缺少或为空,azure_oauth2 可能已使用 Entra ID 的 upn 声明作为电子邮件地址。

配置 Microsoft Azure Active Directory B2C

极狐GitLab 需要特殊配置才能与 Azure Active Directory B2C协同工作。首先,请登录 Azure Portal。对于您的应用,您需要从 Azure 获得以下信息:

  • 租户 ID。
  • 客户端 ID 和客户端密钥。
  • 用户流或策略名称。

配置应用:

  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 指南在 custom policy starter pack 中使用 SocialAndLocalAccounts,但 LocalAccounts 是针对本地 Active Directory 账户进行身份验证。在您上传策略之前,请执行以下操作:

  1. 要导出 email 声明,修改 SignUpOrSignin.xml。替换以下行:

    <OutputClaim ClaimTypeReferenceId="email" />
    

    替换为:

    <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
    
  2. 为使 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>
            ...
    
  3. 上传策略。如果您正在更新现有策略,请覆盖现有文件。

  4. 要确定发行者 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

    确保您包括尾部斜杠。

  5. 验证 OIDC 发现 URL 和发行者 URL 的操作,并在发行者 URL 后附加 .well-known/openid-configuration

    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/"
    
  6. 使用 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,并使用 custom policy tester。确保有效负载包含与用户电子邮件访问匹配的 email
  • 启用自定义策略后,用户可能会在尝试登录后看到 Invalid username or password。这可能是 IdentityExperienceFramework 应用的配置问题。建议您检查应用清单包含以下设置:

    • "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", # do not change this parameter
    label: "Keycloak", # optional label for login button, defaults to "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

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

要使用对称密钥加密:

  1. 从 Keycloak 数据库中提取密钥。Keycloak 不在网络界面中公开该值。网络界面中看到的客户端密钥是 OAuth 2.0 客户端密钥,与用于签署 JSON Web Tokens 的密钥不同。

    例如,如果您使用 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。

  2. value 转换为标准 base64。如 Invalid signature with HS256 token post 中所述,value 是根据 Base 64 Encoding with URL and Filename Safe Alphabet section 的 RFC 4648 编码的。必须将其转换为 RFC 2045 中定义的标准 base64。以下 Ruby 脚本执行此操作:

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

    结果为以下值:

    lo6cqjD6Ika8pk7qc3fpFx9ysrhf7E62+sqGc8drp3XW+wr93zru8PFsQokH\nZZuJJbaUXvmiOftCZM3C4KW3+g==\n
    
  3. jwt_secret_base64 中指定此 base64 编码的密钥。例如:

    gitlab_rails['omniauth_providers'] = [
      {
        name: "openid_connect", # do not change this parameter
        label: "Keycloak", # optional label for login button, defaults to "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

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

gitlab_rails['omniauth_providers'] = [
    {
        name: "openid_connect", # do not change this parameter
        label: "Casdoor", # optional label for login button, defaults to "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', # do not change this parameter
      label: 'Casdoor', # optional label for login button, defaults to "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", # optional label for login button, defaults to "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", # optional label for login button, defaults to "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', # optional label for login button, defaults to "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', # optional label for login button, defaults to "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 组成员身份配置用户

  • 在极狐 GitLab 15.10 中引入。

您可以配置 OIDC 组成员身份来:

  • 要求用户是某个特定组的成员。
  • 根据组成员身份分配用户 外部、管理员或 审计员 角色。

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

必需组

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

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。
  • 登录所需的组成员身份,使用 required_groups 设置。

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

::Tabs

:::TabTitle Linux 软件包 (Omnibus)

  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"]
            }
          }
        }
      }
    ]
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

:::TabTitle 私有化部署 (source)

  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"]
              }
            }
          }
        }
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

::EndTabs

外部组

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

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。
  • 哪些组成员身份应识别用户为 外部用户,使用 external_groups 设置。

::Tabs

:::TabTitle Linux 软件包 (Omnibus)

  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"]
            }
          }
        }
      }
    ]
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

:::TabTitle 私有化部署 (source)

  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"]
              }
            }
          }
        }
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

::EndTabs

审计员组

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

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。
  • 哪些组成员身份授予用户审计员访问权限,使用 auditor_groups 设置。

::Tabs

:::TabTitle Linux 软件包 (Omnibus)

  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"]
            }
          }
        }
      }
    ]
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

:::TabTitle 私有化部署 (source)

  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"]
              }
            }
          }
        }
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

::EndTabs

管理员组

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

  • 在 OIDC 响应中查找组的位置,使用 groups_attribute 设置。
  • 哪些组成员身份授予用户管理员访问权限,使用 admin_groups 设置。

::Tabs

:::TabTitle Linux 软件包 (Omnibus)

  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"]
            }
          }
        }
      }
    ]
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

:::TabTitle 私有化部署 (source)

  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"]
              }
            }
          }
        }
    
  2. 保存文件并 重新配置极狐 GitLab 以使更改生效。

::EndTabs

故障排除

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

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

  3. 如在 OmniAuth OpenID Connect 文档中所述,确保 issuer 对应于 Discovery URL 的基本 URL。例如,https://accounts.example.com 用于 URL https://accounts.example.com/.well-known/openid-configuration

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