InfoGrab Docs

OpenID Connect를 인증 공급자로 사용

요약

OmniAuth 공급자로서 OpenID Connect와 함께 GitLab을 클라이언트 애플리케이션으로 사용할 수 있습니다. OpenID Connect OmniAuth 공급자를 활성화하려면 OpenID Connect 공급자에 애플리케이션을 등록해야 합니다.

OmniAuth 공급자로서 OpenID Connect와 함께 GitLab을 클라이언트 애플리케이션으로 사용할 수 있습니다.

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를 Single Sign-On 공급자로 추가합니다. 이를 통해 기존 GitLab 계정이 없는 사용자에 대한 Just-In-Time 계정 프로비저닝이 활성화됩니다.

  3. 공급자 구성을 추가합니다.

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

    여러 ID 공급자를 사용하는 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'
            }
          }
        }
    

    [!note] 각 구성 옵션에 대한 자세한 내용은 OmniAuth OpenID Connect 사용 설명서OpenID Connect Core 1.0 사양을 참조하십시오.

  4. 공급자 구성에서 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>.
    • discoverytrue로 설정된 경우 OpenID Connect 공급자는 <your_oidc_url>/.well-known/openid-configuration을 사용하여 클라이언트 옵션을 자동으로 검색하려고 합니다. 기본값은 false입니다.
    • client_auth_method (선택 사항)은 OpenID Connect 공급자로 클라이언트를 인증하는 데 사용되는 방법을 지정합니다.
      • 지원되는 값:
        • basic - HTTP Basic 인증.
        • jwt_bearer - JWT 기반 인증(개인 키 및 클라이언트 시크릿 서명).
        • mtls - 상호 TLS 또는 X.509 인증서 유효성 검사.
        • 다른 값은 요청 본문에 클라이언트 ID 및 시크릿을 게시합니다.
      • 지정하지 않으면 이 값의 기본값은 basic입니다.
    • <uid_field> (선택 사항)는 uid 값을 정의하는 user_info.raw_attributes의 필드 이름입니다(예: preferred_username). 이 값을 제공하지 않거나 구성된 값을 가진 필드가 user_info.raw_attributes 세부 정보에서 누락된 경우 uidsub 필드를 사용합니다.
    • send_scope_to_token_endpoint는 기본적으로 true이므로 scope 매개변수는 일반적으로 토큰 엔드포인트에 대한 요청에 포함됩니다. 그러나 OpenID Connect 공급자가 이러한 요청에서 scope 매개변수를 허용하지 않는 경우 이것을 false로 설정합니다.
    • pkce (선택 사항): Proof Key for Code Exchange를 활성화합니다.
    • 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).
      • 다음 client_options는 자동 검색이 비활성화되거나 실패한 경우를 제외하고는 선택 사항입니다:
        • authorization_endpoint는 최종 사용자를 인증하는 엔드포인트의 URL입니다.
        • token_endpoint는 액세스 토큰을 제공하는 엔드포인트의 URL입니다.
        • userinfo_endpoint는 사용자 정보를 제공하는 엔드포인트의 URL입니다.
        • jwks_uri는 토큰 서명자가 키를 게시하는 엔드포인트의 URL입니다.
  5. 구성 파일을 저장합니다.

  6. 변경 사항을 적용하려면 다음과 같이 합니다:

로그인 페이지에서 일반 로그인 양식 아래에 OpenID Connect 옵션이 있습니다. 이 옵션을 선택하여 인증 프로세스를 시작합니다. OpenID Connect 공급자는 클라이언트의 확인이 필요한 경우 로그인하고 GitLab 애플리케이션에 권한을 부여하도록 요청합니다. GitLab으로 리디렉션되고 로그인됩니다.

구성 예시#

다음 구성은 Linux 패키지 설치를 사용할 때 다른 공급자로 OpenID를 설정하는 방법을 보여줍니다.

Google 구성#

자세한 내용은 Google 설명서를 참조하십시오:

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect", # 이 매개변수를 변경하지 마십시오
    label: "Google OpenID", # 로그인 버튼의 선택적 레이블, 기본값은 "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: "",
        secret: "",
        redirect_uri: "https://example.com/users/auth/openid_connect/callback",
       }
     }
  }
]

Microsoft Azure 구성#

Microsoft Azure의 OpenID Connect(OIDC) 프로토콜은 Microsoft ID 플랫폼(v2) 엔드포인트를 사용합니다. 시작하려면 Azure Portal에 로그인합니다. 앱에 대해 다음 정보가 필요합니다:

Microsoft Azure 애플리케이션을 등록할 때 GitLab이 필요한 세부 정보를 검색할 수 있도록 API 권한을 부여해야 합니다. 최소한 openid, profile, email 권한을 제공해야 합니다. 자세한 내용은 웹 API용 앱 권한 구성을 위한 Microsoft 설명서를 참조하십시오.

Note

Azure에서 프로비저닝된 모든 계정에는 이메일 주소가 정의되어 있어야 합니다. 이메일 주소가 정의되어 있지 않으면 Azure는 임의로 생성된 주소를 할당합니다. 도메인 가입 제한을 구성한 경우 이 임의 주소로 인해 계정이 생성되지 않을 수 있습니다.

Linux 패키지 설치용 구성 블록 예시:

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect", # 이 매개변수를 변경하지 마십시오
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
      }
    }
  }
]

Microsoft는 플랫폼이 OIDC 프로토콜과 어떻게 작동하는지 문서화했습니다.

Microsoft Entra 사용자 정의 서명 키#

SAML 클레임 매핑 기능을 사용하기 때문에 애플리케이션에 사용자 정의 서명 키가 있는 경우 다음과 같이 OpenID 공급자를 구성해야 합니다:

  • args.discovery를 생략하거나 false로 설정하여 OpenID Connect 검색을 비활성화합니다.
  • client_options에서 다음을 지정합니다:
    • appid 쿼리 매개변수가 있는 jwks_uri: https://login.microsoftonline.com//discovery/v2.0/keys?appid=.
    • end_session_endpoint.
    • authorization_endpoint.
    • userinfo_endpoint.

Linux 패키지 설치용 구성 예시:

gitlab_rails['omniauth_providers'] = [
 {
    name: "openid_connect", # 이 매개변수를 변경하지 마십시오
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "basic",
      discovery: false,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback",
        end_session_endpoint: "https://login.microsoftonline.com//oauth2/v2.0/logout",
        authorization_endpoint: "https://login.microsoftonline.com//oauth2/v2.0/authorize",
        token_endpoint: "https://login.microsoftonline.com//oauth2/v2.0/token",
        userinfo_endpoint: "https://graph.microsoft.com/oidc/userinfo",
        jwks_uri: "https://login.microsoftonline.com//discovery/v2.0/keys?appid="
      }
    }
  }
]

KidNotFound 메시지와 함께 인증 실패가 발생하는 경우 appid 쿼리 매개변수가 누락되거나 올바르지 않기 때문일 수 있습니다. GitLab은 Microsoft가 반환한 ID 토큰이 jwks_uri 엔드포인트에서 제공한 키로 유효성을 검사할 수 없는 경우 해당 오류를 발생시킵니다.

자세한 내용은 토큰 유효성 검사에 대한 Microsoft Entra 설명서를 참조하십시오.

일반 OpenID Connect 구성으로 마이그레이션#

azure_activedirectory_v2azure_oauth2 모두에서 일반 OpenID Connect 구성으로 마이그레이션할 수 있습니다.

먼저 uid_field를 설정합니다. uid_fielduid_field로 선택할 수 있는 sub 클레임은 모두 공급자에 따라 다릅니다. uid_field를 설정하지 않고 로그인하면 GitLab에 수동으로 수정해야 하는 추가 ID가 생성됩니다:

공급자 uid_field 지원 정보
omniauth-azure-oauth2 sub 추가 속성 oidtidinfo 객체에 제공됩니다.
omniauth-azure-activedirectory-v2 oid 마이그레이션할 때 oiduid_field로 구성해야 합니다.
omniauth_openid_connect sub 다른 필드를 사용하려면 uid_field를 지정하십시오.

일반 OpenID Connect 구성으로 마이그레이션하려면 구성을 업데이트해야 합니다.

Linux 패키지 설치의 경우 다음과 같이 구성을 업데이트합니다:

gitlab_rails['omniauth_providers'] = [
  {
    name: "azure_oauth2",
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "azure_oauth2", # 기존 azure_oauth2 공급자 이름과 일치하며, 바로 아래 strategy_class만 OpenID Connect를 구성합니다
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "sub",
      send_scope_to_token_endpoint: "false",
      client_options: {
        identifier: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/azure_oauth2/callback"
      }
    }
  }
]
gitlab_rails['omniauth_providers'] = [
  {
    name: "azure_activedirectory_v2",
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "azure_activedirectory_v2",
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "oid",
      send_scope_to_token_endpoint: "false",
      client_options: {
        identifier: "",
        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//v2.0",
    "client_auth_method": "query",
    "discovery": true,
    "uid_field": "sub",
    "send_scope_to_token_endpoint": false,
    "client_options": {
      "identifier": "",
      "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//v2.0",
    "client_auth_method": "query",
    "discovery": true,
    "uid_field": "sub",
    "send_scope_to_token_endpoint": false,
    "client_options": {
      "identifier": "",
      "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에 이메일 주소가 있는 사용자의 경우, 이메일 주소로 폴백하고 사용자 ID를 업데이트할 수 있도록 다음을 구성합니다:
  • 이메일 주소가 없는 사용자의 경우, 관리자는 다음 작업 중 하나를 수행해야 합니다:
    • 다른 인증 방법을 설정하거나 GitLab 사용자 이름 및 비밀번호를 사용한 로그인을 활성화합니다. 그러면 사용자가 로그인하고 프로필을 사용하여 수동으로 Azure ID를 연결할 수 있습니다.
    • 기존 azure_oauth2와 함께 OpenID Connect를 새 공급자로 구현하여 사용자가 OAuth 2.0을 통해 로그인하고 OpenID Connect ID를 연결할 수 있도록 합니다(이전 방법과 유사). 이 방법은 auto_link_user가 활성화된 경우 이메일 주소가 있는 사용자에게도 작동합니다.
    • extern_uid를 수동으로 업데이트합니다. 이를 위해 API 또는 Rails 콘솔을 사용하여 각 사용자의 extern_uid를 업데이트합니다. 인스턴스가 이미 17.0 이상으로 업그레이드되었고 사용자가 로그인을 시도한 경우 이 방법이 필요할 수 있습니다.
Note

azure_oauth2는 GitLab 계정을 프로비저닝할 때 email 클레임이 누락되거나 비어 있는 경우 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 URIhttps://gitlab.example.com/users/auth/openid_connect/callback으로 설정합니다.

  2. ID 토큰 활성화.

  3. 앱에 다음 API 권한을 추가합니다:

    • openid
    • offline_access

사용자 정의 정책 구성#

Azure B2C는 사용자 로그인을 위한 비즈니스 로직을 정의하는 두 가지 방법을 제공합니다:

표준 Azure B2C 사용자 흐름은 GitLab이 사용자를 생성하거나 연결하는 데 필요한 OpenID email 클레임을 보내지 않기 때문에 사용자 정의 정책이 필요합니다. 따라서 표준 사용자 흐름은 allow_single_sign_on 또는 auto_link_user 매개변수와 함께 작동하지 않습니다. 표준 Azure B2C 정책으로는 GitLab이 새 계정을 만들거나 이메일 주소를 사용하는 기존 계정에 연결할 수 없습니다.

사용자 흐름과 사용자 정의 정책에서 Azure AD B2C가 토큰과 클레임을 발행하는 방법에 대한 자세한 내용은 사용자 흐름과 사용자 정의 정책클레임 스키마 구성에 대한 Microsoft 설명서를 참조하십시오.

먼저 사용자 정의 정책을 만듭니다.

Microsoft 지침은 사용자 정의 정책 스타터 팩에서 SocialAndLocalAccounts를 사용하지만 LocalAccounts는 로컬 Active Directory 계정에 대해 인증합니다. 정책을 업로드하기 전에 다음을 수행합니다:

  1. email 클레임을 내보내려면 SignUpOrSignin.xml을 수정합니다. 다음 줄을 교체합니다:

    <OutputClaim ClaimTypeReferenceId="email" />
    

    다음으로:

    <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
    
  2. B2C로 OIDC 검색이 작동하려면 OIDC 사양과 호환되는 발급자로 정책을 구성합니다. 토큰 호환성 설정을 참조하십시오. JwtIssuer 아래 TrustFrameworkBase.xml에서 IssuanceClaimPatternAuthorityWithTfp로 설정합니다:

    <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", # 이 매개변수를 변경하지 마십시오
      label: "Azure B2C OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
      args: {
        name: "openid_connect",
        scope: ["openid"],
        response_mode: "query",
        response_type: "id_token",
        issuer:  "https:///tfp//b2c_1a_signup_signin/v2.0/",
        client_auth_method: "query",
        discovery: true,
        send_scope_to_token_endpoint: true,
        pkce: true,
        client_options: {
          identifier: "",
          secret: "",
          redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
        }
      }
    }]
    

Azure B2C 문제 해결#

  • XML 정책 파일에서 yourtenant.onmicrosoft.com, ProxyIdentityExperienceFrameworkAppId, IdentityExperienceFrameworkAppId의 모든 항목이 B2C 테넌트 호스트 이름 및 해당 클라이언트 ID와 일치하는지 확인합니다.

  • https://jwt.ms를 앱의 리디렉션 URI로 추가하고 사용자 정의 정책 테스터를 사용합니다. 페이로드에 사용자의 이메일 액세스와 일치하는 email이 포함되어 있는지 확인합니다.

  • 사용자 정의 정책을 활성화한 후 사용자가 로그인하려고 할 때 Invalid username or password가 표시될 수 있습니다. 이것은 IdentityExperienceFramework 앱의 구성 문제일 수 있습니다. 앱 매니페스트에 다음 설정이 포함되어 있는지 확인하라고 제안하는 이 Microsoft 댓글을 참조하십시오:

    • "accessTokenAcceptedVersion": null
    • "signInAudience": "AzureADMyOrg"

이 구성은 IdentityExperienceFramework 앱을 만들 때 사용되는 Supported account types 설정에 해당합니다.

Keycloak 구성#

GitLab은 HTTPS를 사용하는 OpenID 공급자와 함께 작동합니다. HTTP를 사용하는 Keycloak 서버를 설정할 수 있지만 GitLab은 HTTPS를 사용하는 Keycloak 서버와만 통신할 수 있습니다.

Keycloak을 구성하여 공개 키 알고리즘을 사용하여 토큰에 서명합니다. 예를 들어 HS256 또는 HS358 대신 RSA256 또는 RSA512를 사용합니다. 공개 키 암호화 알고리즘은:

  • 구성하기 더 쉽습니다.
  • 개인 키를 유출하면 심각한 보안 결과를 초래하기 때문에 더 안전합니다.
  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: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
      }
    }
  }
]

대칭 키 알고리즘으로 Keycloak 구성#

Warning

다음 지침은 완전성을 위해 포함되었지만 절대적으로 필요한 경우에만 대칭 키 암호화를 사용하십시오.

대칭 키 암호화를 사용하려면:

  1. Keycloak 데이터베이스에서 시크릿 키를 추출합니다. Keycloak은 웹 인터페이스에서 이 값을 노출하지 않습니다. 웹 인터페이스에서 볼 수 있는 클라이언트 시크릿은 JSON Web Token에 서명하는 데 사용되는 시크릿과 다른 OAuth 2.0 클라이언트 시크릿입니다.

    예를 들어 Keycloak의 백엔드 데이터베이스로 PostgreSQL을 사용하는 경우:

    • 데이터베이스 콘솔에 로그인합니다.

    • 다음 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)에 대한 키. GitLab을 구성하는 데 첫 번째 value를 사용합니다.

  2. value를 표준 base64로 변환합니다. "Invalid signature with HS256 token" 포스트에서 논의된 바와 같이 value는 RFC 4648의 "URL 및 파일 이름 안전 알파벳으로 Base 64 인코딩" 섹션으로 인코딩됩니다. 이것은 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", # 이 매개변수를 변경하지 마십시오
        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: "",
          pkce: true,
          client_options: {
            identifier: "",
            secret: "",
            redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
          }
        }
      }
    ]
    

JSON::JWS::VerificationFailed 오류가 표시되면 잘못된 시크릿을 지정한 것입니다.

Casdoor#

GitLab은 HTTPS를 사용하는 OpenID 공급자와 함께 작동합니다. HTTPS를 사용하여 Casdoor를 통해 OpenID로 GitLab에 연결합니다.

앱에 대해 Casdoor에서 다음 단계를 완료합니다:

  1. 클라이언트 ID와 클라이언트 시크릿을 얻습니다.
  2. GitLab 리디렉션 URL을 추가합니다. 예를 들어 GitLab 도메인이 gitlab.example.com인 경우 Casdoor 앱에 다음 Redirect URI가 있는지 확인합니다: https://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://",
            client_auth_method: "query",
            discovery: true,
            uid_field: "sub",
            client_options: {
                identifier: "",
                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://',
        discovery: true,
        client_auth_method: 'query',
        uid_field: 'sub',
        client_options: {
          identifier: '',
          secret: '',
          redirect_uri: 'https://gitlab.example.com/users/auth/openid_connect/callback'
        }
      }
    }

여러 OpenID Connect 공급자 구성#

여러 OpenID Connect(OIDC) 공급자를 사용하도록 애플리케이션을 구성할 수 있습니다. 이를 위해 구성 파일에서 strategy_class를 명시적으로 설정합니다.

다음 시나리오 중 하나에서 이를 수행해야 합니다:

다음 구성 예시는 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 그룹 구성원 자격을 기반으로 사용자 구성#

OIDC 그룹 구성원 자격을 구성할 수 있습니다:

  • 사용자가 특정 그룹의 구성원이 되도록 요구.
  • 그룹 구성원 자격에 따라 사용자에게 외부, 관리자 또는 감사자 역할 할당.

GitLab은 각 로그인 시 이러한 그룹을 확인하고 필요에 따라 사용자 속성을 업데이트합니다. 이 기능을 사용하면 사용자를 GitLab 그룹에 자동으로 추가할 수 없습니다.

특정 그룹에 정의된 값은 ID 공급자가 반환하는 값을 반영해야 합니다. 예를 들어 Microsoft Entra OIDC는 GroupID를 반환하므로 required_groups 구성은 required_groups: ["55db8574-c392-4e8b-892d-1e086394be9c"]와 같이 표시됩니다.

필수 그룹#

ID 공급자(IdP)는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 사용자가 특정 그룹의 구성원이 되도록 요구하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

외부 그룹#

IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 그룹 구성원 자격을 기반으로 사용자를 외부 사용자로 식별하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

감사자 그룹#

IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 그룹 구성원 자격에 따라 사용자를 감사자로 할당하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

관리자 그룹#

IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 그룹 구성원 자격에 따라 사용자를 관리자로 할당하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

ID 토큰에 대한 사용자 정의 기간 구성#

히스토리

기본적으로 GitLab ID 토큰은 120초 후에 만료됩니다.

ID 토큰에 대한 사용자 정의 기간을 구성하려면:

  1. /etc/gitlab/gitlab.rb를 편집합니다:

    gitlab_rails['oidc_provider_openid_id_token_expire_in_seconds'] = 3600
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

  1. /home/git/gitlab/config/gitlab.yml을 편집합니다:

    production: &base
      oidc_provider:
       openid_id_token_expire_in_seconds: 3600
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

단계적 인증(Step-up authentication)#

Feature flag

이 기능의 가용성은 기능 플래그로 제어됩니다. 자세한 내용은 기록을 참조하십시오. 이 기능은 테스트용으로 사용할 수 있지만 프로덕션 사용에는 준비가 되지 않았습니다.

경우에 따라 기본 인증 방법이 중요한 리소스나 고위험 작업을 보호하지 못합니다. 단계적 인증은 권한 있는 작업이나 민감한 작업에 추가 레이어를 추가합니다. 예를 들어 Admin 영역에 액세스할 때.

단계적 인증을 사용하면 사용자는 특정 기능에 액세스하기 전에 등록된 이중 인증 방법으로 추가 인증을 완료해야 합니다.

OIDC 표준에는 인증 컨텍스트 클래스 참조(ACR)가 포함됩니다. ACR 개념은 Admin 모드와 같은 다양한 시나리오에 대한 단계적 인증을 구성하고 구현하는 데 도움이 됩니다.

이 기능은 실험이며 예고 없이 변경될 수 있습니다. 이 기능은 프로덕션 사용에 준비가 되지 않았습니다. 이 기능을 사용하려면 먼저 프로덕션 외부에서 테스트해야 합니다.

Admin 모드에 단계적 인증 활성화#

히스토리
  • GitLab 17.11에서 omniauth_step_up_auth_for_admin_mode라는 플래그와 함께 도입됨. 기본적으로 비활성화됨.

Admin 모드에 단계적 인증을 활성화하려면:

  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'(Authentication Context Class Reference) 클레임은
                  # 단계적 인증 과제를 통과하기 위해 'gold' 값을 가져야 합니다.
                  # 이를 통해 특정 수준의 인증 보증이 보장됩니다.
                  required: {
                    acr: 'gold'
                  },
                  # `included` 필드도 ID 토큰에 포함되어야 하는 키-값 쌍을 정의합니다.
                  # 배열에 여러 허용 값을 정의할 수 있습니다. 배열이 사용되지 않으면 값이 정확히 일치해야 합니다.
                  # 이 예시에서 'amr'(Authentication Method References) 클레임은
                  # 단계적 인증 과제를 통과하기 위해 'mfa' 또는 'fpt' 값을 가져야 합니다.
                  # 이는 사용자가 추가 인증 요소를 제공해야 하는 시나리오에 유용합니다.
                  included: {
                    amr: ['mfa', 'fpt']
                  },
                },
                # `params` 필드는 인증 프로세스 중에 전송되는 추가 매개변수를 정의합니다.
                # 이 예시에서 `claims` 매개변수는 인증 요청에 추가되어
                # ID 토큰에 'gold' 값으로 'acr' 클레임을 포함하도록 ID 공급자에 지시합니다.
                # 'essential: true'는 이 클레임이 성공적인 인증에 필요함을 나타냅니다.
                params: {
                  claims: {
                    id_token: {
                      acr: {
                        essential: true,
                        values: ['gold']
                      }
                    }
                  }
                },
                # 선택 사항: 단계적 인증에 실패한 사용자를 위한 사용자 정의 설명서 링크 제공
                # 이 링크는 단계적 인증이 실패할 때 표시되어 사용자를 조직별 인증 설명서로 안내합니다.
                documentation_link: 'https://internal.example.com/path/to/documentation'
              },
            }
          }
    
  2. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

Note

OIDC는 표준화되어 있지만 서로 다른 ID 공급자(IdP)는 고유한 요구 사항을 가질 수 있습니다. params 설정은 단계적 인증에 필요한 매개변수를 정의하기 위한 유연한 해시를 허용합니다. 이러한 값은 각 IdP의 요구 사항에 따라 다를 수 있습니다.

Keycloak을 사용한 단계적 인증 요구#

Keycloak은 인증 수준 정의 및 사용자 정의 브라우저 로그인 흐름을 통해 단계적 인증을 지원합니다.

Keycloak을 사용한 Admin 모드에 단계적 인증을 요구하려면:

  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"] # `step_up_auth => admin_mode => params`에 정의된 매개변수와 일치
            },
            step_up_auth: {
              admin_mode: {
                id_token: {
                  # 이 예시에서 'acr' 클레임은 Keycloak 설명서에도 정의된 'gold' 값을 가져야 합니다.
                  required: {
                    acr: 'gold'
                  }
                },
                params: {
                  claims: {
                    id_token: {
                      acr: { essential: true, values: ['gold'] }
                    }
                  },
                },
                # 선택 사항: Keycloak별 단계적 인증 도움말을 위한 사용자 정의 설명서 링크 추가
                documentation_link: 'https://internal.example.com/path/to/documentation'
              },
            }
          }
    
  4. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

Microsoft Entra ID를 사용한 단계적 인증 요구#

Microsoft Entra ID(이전의 Azure Active Directory)는 조건부 액세스 인증 컨텍스트를 통해 단계적 인증을 지원합니다. 올바른 구성을 정의하려면 Microsoft Entra ID 관리자와 협력해야 합니다.

다음 측면을 고려하십시오:

  • 인증 컨텍스트 ID는 다른 ID 공급자에 사용되는 ID 토큰 클레임 acr이 아닌 acrs 클레임을 통해서만 요청됩니다.
  • 인증 컨텍스트 ID는 c1에서 c99까지의 고정 값을 사용하며 각 값은 조건부 액세스 정책이 있는 특정 인증 컨텍스트를 나타냅니다.
  • 기본적으로 Microsoft Entra ID는 ID 토큰에 acrs 클레임을 포함하지 않습니다. 이를 활성화하려면 선택적 클레임 구성을 해야 합니다.
  • 단계적 인증이 성공하면 응답은 acrs 클레임을 문자열의 JSON 배열로 반환합니다. 예를 들어: acrs: ["c1", "c2", "c3"].

Microsoft Entra ID를 사용한 Admin 모드에 단계적 인증을 요구하려면:

  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"] # `step_up_auth => admin_mode => params`에 정의된 매개변수와 일치
          },
          step_up_auth: {
            admin_mode: {
              id_token: {
                # 이 예시에서 Microsoft Entra ID 관리자는 원하는 보안 수준을 가진
                # 인증 컨텍스트 ID로 `c20`을 정의하고 ID 토큰에 포함될 선택적 클레임 `acrs`를 정의했습니다.
                # `included` 필드는 id 토큰 클레임 `acrs`에 `c20` 값이 포함되어야 함을 선언합니다.
                included: {
                  acrs: ["c20"],
                },
              },
              params: {
                claims: {
                  id_token: {
                    acrs: { essential: true, value: 'c20' }
                  }
                },
              },
              # 선택 사항: Microsoft Entra ID 단계적 인증을 위한 사용자 정의 설명서 링크 추가
              documentation_link: 'https://internal.example.com/path/to/documentation'
            },
          }
        }
    
  5. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

그룹에 단계적 인증 공급자 추가#

히스토리
  • GitLab 18.4에서 omniauth_step_up_auth_for_namespace라는 플래그와 함께 도입됨. 기본적으로 비활성화됨.

인스턴스의 모든 그룹에서 사용 가능한 단계적 인증 공급자를 추가할 수도 있습니다. 이렇게 하면 그룹에서 단계적 인증을 강제할 수 없으며 각 그룹은 여전히 설정해야 합니다.

그룹에 단계적 인증 공급자를 추가하려면:

  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 모드에 대한 단계적 인증 구성과 달리 `namespace` 객체를 사용합니다.
              # 이는 Admin 모드만이 아닌 전체 그룹에 대한 액세스에 단계적 인증을 추가하기 때문입니다.
              namespace : {
                # `id_token` 필드는 토큰에 포함되어야 하는 클레임을 정의합니다.
                # `required` 또는 `included` 필드 중 하나 또는 둘 다에 클레임을 지정할 수 있습니다.
                # 토큰은 이러한 필드에 정의하는 모든 클레임에 대해 일치하는 값을 포함해야 합니다.
                id_token: {
                  # `required` 필드는 ID 토큰에 포함되어야 하는 키-값 쌍을 정의합니다.
                  # 값은 정의된 것과 정확히 일치해야 합니다.
                  required: {
                    acr: 'gold'
                  },
                  # `included` 필드도 ID 토큰에 포함되어야 하는 키-값 쌍을 정의합니다.
                  included: {
                    amr: ['mfa', 'fpt']
                  },
                },
                # `params` 필드는 인증 프로세스 중에 전송되는 추가 매개변수를 정의합니다.
                params: {
                  claims: {
                    id_token: {
                      acr: {
                        essential: true,
                        values: ['gold']
                      }
                    }
                  }
                }
              },
            }
          }
    
  2. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

그룹에 단계적 인증 강제#

사용자가 그룹에 액세스하기 전에 단계적 인증을 완료하도록 강제할 수 있습니다. 이 설정은 각 그룹에 대해 개별적으로 관리되지만 이전에 전체 인스턴스에 추가된 단계적 인증 공급자가 필요합니다.

사전 요구 사항:

그룹에 단계적 인증을 강제하려면:

  1. 상단 표시줄에서 Search or go to를 선택하고 그룹을 찾습니다.
  2. Settings > General을 선택합니다.
  3. Permissions and group features 섹션을 확장합니다.
  4. 단계적 인증 아래에서 사용 가능한 인증 공급자를 선택합니다.
  5. Save changes를 선택합니다.

단계적 인증에 사용자 정의 설명서 링크 추가#

단계적 인증이 실패하면 GitLab은 사용자가 조직의 인증 요구 사항을 이해하는 데 도움이 되는 사용자 정의 설명서 링크를 표시할 수 있습니다. 이 기능을 통해 관리자는 내부 설명서나 도움 리소스로 사용자를 안내하는 조직별 지침을 제공할 수 있습니다.

사용자 정의 설명서 링크를 추가하려면:

  1. GitLab 구성 파일(gitlab.yml 또는 /etc/gitlab/gitlab.rb)을 편집하여 step_up_auth => admin_modedocumentation_link 필드를 추가합니다.

    production: &base
      omniauth:
        providers:
        - { name: 'openid_connect',
            label: 'Corporate SSO',
            # ... 다른 공급자 구성 ...
            step_up_auth: {
              admin_mode: {
                # ... id_token 및 params 구성 ...
                documentation_link: 'https://internal.example.com/path/to/documentation'
              }
            }
          }
    
  2. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

사용자가 단계적 인증에 실패하면 실패한 공급자에 대한 관련 설명서 링크가 포함된 도움이 되는 오류 메시지가 표시됩니다. 링크는 단계적 인증이 실제로 실패한 공급자에 대해서만 표시되므로 지침이 더 관련성이 높고 실행 가능합니다.

Note

설명서 링크 모범 사례:

  • 보안을 위해 HTTPS URL을 사용합니다.
  • 조직의 특정 인증 요구 사항을 설명하는 내부 설명서로 링크합니다.
  • MFA 또는 다른 필수 인증 방법을 활성화하는 방법에 대한 정보를 포함합니다.

세션 만료 비활성화#

기본적으로 단계적 인증 세션은 ID 공급자(IdP) 토큰 만료 시간(일반적으로 약 10분)에 따라 만료됩니다.

session_expiration_enabled 설정으로 세션 만료를 제어할 수 있습니다:

설정 동작
session_expiration_enabled: true (기본값) 단계적 인증은 IdP 토큰 exp 클레임에 따라 만료됩니다. 일반적으로 약 10분입니다.
session_expiration_enabled: false 단계적 인증은 사용자가 로그아웃할 때까지 전체 사용자 세션 동안 유효합니다.
Warning

세션 만료를 비활성화하면 사용자가 주기적으로 ID를 재확인하는 대신 세션당 한 번만 인증합니다. 보안 요구 사항이 세션 수명 단계적 인증을 허용하는 경우에만 이 설정을 비활성화하십시오.

세션 만료를 비활성화하려면:

  1. /etc/gitlab/gitlab.rb를 편집합니다:

    gitlab_rails['omniauth_providers'] = [
      {
        name: "openid_connect",
        label: "Provider name",
        args: {
          name: "openid_connect",
          # ... 다른 args ...
        },
        step_up_auth: {
          session_expiration_enabled: false,  # 세션 만료 비활성화
          admin_mode: {
            # ... admin_mode 구성 ...
          },
          namespace: {
            # ... namespace 구성 ...
          }
        }
      }
    ]
    
  2. 파일을 저장하고 GitLab을 재구성합니다:

    sudo gitlab-ctl reconfigure
    
  1. config/gitlab.yml을 편집합니다:

    production: &base
      omniauth:
        providers:
          - { name: 'openid_connect',
              label: 'Provider name',
              args: {
                name: 'openid_connect',
                # ... 다른 args ...
              },
              step_up_auth: {
                session_expiration_enabled: false,
                admin_mode: {
                  # ... admin_mode 구성 ...
                },
                namespace: {
                  # ... namespace 구성 ...
                }
              }
            }
    
  2. 파일을 저장하고 GitLab을 재시작합니다:

    # systemd를 실행하는 시스템의 경우
    sudo systemctl restart gitlab.target
    
    # SysV init을 실행하는 시스템의 경우
    sudo service gitlab restart
    

문제 해결#

  1. discoverytrue로 설정되어 있는지 확인합니다. false로 설정하면 OpenID가 작동하는 데 필요한 모든 URL과 키를 지정해야 합니다.
  2. 시스템 시계를 확인하여 시간이 올바르게 동기화되었는지 확인합니다.
  3. OmniAuth OpenID Connect 설명서에 언급된 것처럼 issuer가 검색 URL의 기본 URL에 해당하는지 확인합니다. 예를 들어 https://accounts.google.com은 URL https://accounts.google.com/.well-known/openid-configuration에 사용됩니다.
  4. OpenID Connect 클라이언트는 client_auth_method가 정의되지 않았거나 basic으로 설정된 경우 HTTP Basic 인증을 사용하여 OAuth 2.0 액세스 토큰을 전송합니다. userinfo 엔드포인트를 검색할 때 401 오류가 표시되면 OpenID 웹 서버 구성을 확인합니다. 예를 들어 oauth2-server-php의 경우 Apache에 구성 매개변수를 추가해야 할 수 있습니다.
  5. 단계적 인증 전용: step_up_auth => admin_mode => params에 정의된 모든 매개변수가 args => allow_authorize_params에도 정의되어 있는지 확인합니다. 여기에는 IdP 인증 엔드포인트로 리디렉션하는 데 사용되는 요청 쿼리 매개변수의 매개변수가 포함됩니다.

OpenID Connect를 인증 공급자로 사용

Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기
요약

OmniAuth 공급자로서 OpenID Connect와 함께 GitLab을 클라이언트 애플리케이션으로 사용할 수 있습니다. OpenID Connect OmniAuth 공급자를 활성화하려면 OpenID Connect 공급자에 애플리케이션을 등록해야 합니다.

OmniAuth 공급자로서 OpenID Connect와 함께 GitLab을 클라이언트 애플리케이션으로 사용할 수 있습니다.

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를 Single Sign-On 공급자로 추가합니다. 이를 통해 기존 GitLab 계정이 없는 사용자에 대한 Just-In-Time 계정 프로비저닝이 활성화됩니다.

  3. 공급자 구성을 추가합니다.

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

    여러 ID 공급자를 사용하는 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'
            }
          }
        }
    

    [!note] 각 구성 옵션에 대한 자세한 내용은 OmniAuth OpenID Connect 사용 설명서OpenID Connect Core 1.0 사양을 참조하십시오.

  4. 공급자 구성에서 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>.
    • discoverytrue로 설정된 경우 OpenID Connect 공급자는 <your_oidc_url>/.well-known/openid-configuration을 사용하여 클라이언트 옵션을 자동으로 검색하려고 합니다. 기본값은 false입니다.
    • client_auth_method (선택 사항)은 OpenID Connect 공급자로 클라이언트를 인증하는 데 사용되는 방법을 지정합니다.
      • 지원되는 값:
        • basic - HTTP Basic 인증.
        • jwt_bearer - JWT 기반 인증(개인 키 및 클라이언트 시크릿 서명).
        • mtls - 상호 TLS 또는 X.509 인증서 유효성 검사.
        • 다른 값은 요청 본문에 클라이언트 ID 및 시크릿을 게시합니다.
      • 지정하지 않으면 이 값의 기본값은 basic입니다.
    • <uid_field> (선택 사항)는 uid 값을 정의하는 user_info.raw_attributes의 필드 이름입니다(예: preferred_username). 이 값을 제공하지 않거나 구성된 값을 가진 필드가 user_info.raw_attributes 세부 정보에서 누락된 경우 uidsub 필드를 사용합니다.
    • send_scope_to_token_endpoint는 기본적으로 true이므로 scope 매개변수는 일반적으로 토큰 엔드포인트에 대한 요청에 포함됩니다. 그러나 OpenID Connect 공급자가 이러한 요청에서 scope 매개변수를 허용하지 않는 경우 이것을 false로 설정합니다.
    • pkce (선택 사항): Proof Key for Code Exchange를 활성화합니다.
    • 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).
      • 다음 client_options는 자동 검색이 비활성화되거나 실패한 경우를 제외하고는 선택 사항입니다:
        • authorization_endpoint는 최종 사용자를 인증하는 엔드포인트의 URL입니다.
        • token_endpoint는 액세스 토큰을 제공하는 엔드포인트의 URL입니다.
        • userinfo_endpoint는 사용자 정보를 제공하는 엔드포인트의 URL입니다.
        • jwks_uri는 토큰 서명자가 키를 게시하는 엔드포인트의 URL입니다.
  5. 구성 파일을 저장합니다.

  6. 변경 사항을 적용하려면 다음과 같이 합니다:

로그인 페이지에서 일반 로그인 양식 아래에 OpenID Connect 옵션이 있습니다. 이 옵션을 선택하여 인증 프로세스를 시작합니다. OpenID Connect 공급자는 클라이언트의 확인이 필요한 경우 로그인하고 GitLab 애플리케이션에 권한을 부여하도록 요청합니다. GitLab으로 리디렉션되고 로그인됩니다.

구성 예시#

다음 구성은 Linux 패키지 설치를 사용할 때 다른 공급자로 OpenID를 설정하는 방법을 보여줍니다.

Google 구성#

자세한 내용은 Google 설명서를 참조하십시오:

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect", # 이 매개변수를 변경하지 마십시오
    label: "Google OpenID", # 로그인 버튼의 선택적 레이블, 기본값은 "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: "",
        secret: "",
        redirect_uri: "https://example.com/users/auth/openid_connect/callback",
       }
     }
  }
]

Microsoft Azure 구성#

Microsoft Azure의 OpenID Connect(OIDC) 프로토콜은 Microsoft ID 플랫폼(v2) 엔드포인트를 사용합니다. 시작하려면 Azure Portal에 로그인합니다. 앱에 대해 다음 정보가 필요합니다:

Microsoft Azure 애플리케이션을 등록할 때 GitLab이 필요한 세부 정보를 검색할 수 있도록 API 권한을 부여해야 합니다. 최소한 openid, profile, email 권한을 제공해야 합니다. 자세한 내용은 웹 API용 앱 권한 구성을 위한 Microsoft 설명서를 참조하십시오.

Note

Azure에서 프로비저닝된 모든 계정에는 이메일 주소가 정의되어 있어야 합니다. 이메일 주소가 정의되어 있지 않으면 Azure는 임의로 생성된 주소를 할당합니다. 도메인 가입 제한을 구성한 경우 이 임의 주소로 인해 계정이 생성되지 않을 수 있습니다.

Linux 패키지 설치용 구성 블록 예시:

gitlab_rails['omniauth_providers'] = [
  {
    name: "openid_connect", # 이 매개변수를 변경하지 마십시오
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
      }
    }
  }
]

Microsoft는 플랫폼이 OIDC 프로토콜과 어떻게 작동하는지 문서화했습니다.

Microsoft Entra 사용자 정의 서명 키#

SAML 클레임 매핑 기능을 사용하기 때문에 애플리케이션에 사용자 정의 서명 키가 있는 경우 다음과 같이 OpenID 공급자를 구성해야 합니다:

  • args.discovery를 생략하거나 false로 설정하여 OpenID Connect 검색을 비활성화합니다.
  • client_options에서 다음을 지정합니다:
    • appid 쿼리 매개변수가 있는 jwks_uri: https://login.microsoftonline.com//discovery/v2.0/keys?appid=.
    • end_session_endpoint.
    • authorization_endpoint.
    • userinfo_endpoint.

Linux 패키지 설치용 구성 예시:

gitlab_rails['omniauth_providers'] = [
 {
    name: "openid_connect", # 이 매개변수를 변경하지 마십시오
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "openid_connect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "basic",
      discovery: false,
      uid_field: "preferred_username",
      pkce: true,
      client_options: {
        identifier: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback",
        end_session_endpoint: "https://login.microsoftonline.com//oauth2/v2.0/logout",
        authorization_endpoint: "https://login.microsoftonline.com//oauth2/v2.0/authorize",
        token_endpoint: "https://login.microsoftonline.com//oauth2/v2.0/token",
        userinfo_endpoint: "https://graph.microsoft.com/oidc/userinfo",
        jwks_uri: "https://login.microsoftonline.com//discovery/v2.0/keys?appid="
      }
    }
  }
]

KidNotFound 메시지와 함께 인증 실패가 발생하는 경우 appid 쿼리 매개변수가 누락되거나 올바르지 않기 때문일 수 있습니다. GitLab은 Microsoft가 반환한 ID 토큰이 jwks_uri 엔드포인트에서 제공한 키로 유효성을 검사할 수 없는 경우 해당 오류를 발생시킵니다.

자세한 내용은 토큰 유효성 검사에 대한 Microsoft Entra 설명서를 참조하십시오.

일반 OpenID Connect 구성으로 마이그레이션#

azure_activedirectory_v2azure_oauth2 모두에서 일반 OpenID Connect 구성으로 마이그레이션할 수 있습니다.

먼저 uid_field를 설정합니다. uid_fielduid_field로 선택할 수 있는 sub 클레임은 모두 공급자에 따라 다릅니다. uid_field를 설정하지 않고 로그인하면 GitLab에 수동으로 수정해야 하는 추가 ID가 생성됩니다:

공급자 uid_field 지원 정보
omniauth-azure-oauth2 sub 추가 속성 oidtidinfo 객체에 제공됩니다.
omniauth-azure-activedirectory-v2 oid 마이그레이션할 때 oiduid_field로 구성해야 합니다.
omniauth_openid_connect sub 다른 필드를 사용하려면 uid_field를 지정하십시오.

일반 OpenID Connect 구성으로 마이그레이션하려면 구성을 업데이트해야 합니다.

Linux 패키지 설치의 경우 다음과 같이 구성을 업데이트합니다:

gitlab_rails['omniauth_providers'] = [
  {
    name: "azure_oauth2",
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "azure_oauth2", # 기존 azure_oauth2 공급자 이름과 일치하며, 바로 아래 strategy_class만 OpenID Connect를 구성합니다
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "sub",
      send_scope_to_token_endpoint: "false",
      client_options: {
        identifier: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/azure_oauth2/callback"
      }
    }
  }
]
gitlab_rails['omniauth_providers'] = [
  {
    name: "azure_activedirectory_v2",
    label: "Azure OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
    args: {
      name: "azure_activedirectory_v2",
      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
      scope: ["openid", "profile", "email"],
      response_type: "code",
      issuer:  "https://login.microsoftonline.com//v2.0",
      client_auth_method: "query",
      discovery: true,
      uid_field: "oid",
      send_scope_to_token_endpoint: "false",
      client_options: {
        identifier: "",
        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//v2.0",
    "client_auth_method": "query",
    "discovery": true,
    "uid_field": "sub",
    "send_scope_to_token_endpoint": false,
    "client_options": {
      "identifier": "",
      "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//v2.0",
    "client_auth_method": "query",
    "discovery": true,
    "uid_field": "sub",
    "send_scope_to_token_endpoint": false,
    "client_options": {
      "identifier": "",
      "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에 이메일 주소가 있는 사용자의 경우, 이메일 주소로 폴백하고 사용자 ID를 업데이트할 수 있도록 다음을 구성합니다:
  • 이메일 주소가 없는 사용자의 경우, 관리자는 다음 작업 중 하나를 수행해야 합니다:
    • 다른 인증 방법을 설정하거나 GitLab 사용자 이름 및 비밀번호를 사용한 로그인을 활성화합니다. 그러면 사용자가 로그인하고 프로필을 사용하여 수동으로 Azure ID를 연결할 수 있습니다.
    • 기존 azure_oauth2와 함께 OpenID Connect를 새 공급자로 구현하여 사용자가 OAuth 2.0을 통해 로그인하고 OpenID Connect ID를 연결할 수 있도록 합니다(이전 방법과 유사). 이 방법은 auto_link_user가 활성화된 경우 이메일 주소가 있는 사용자에게도 작동합니다.
    • extern_uid를 수동으로 업데이트합니다. 이를 위해 API 또는 Rails 콘솔을 사용하여 각 사용자의 extern_uid를 업데이트합니다. 인스턴스가 이미 17.0 이상으로 업그레이드되었고 사용자가 로그인을 시도한 경우 이 방법이 필요할 수 있습니다.
Note

azure_oauth2는 GitLab 계정을 프로비저닝할 때 email 클레임이 누락되거나 비어 있는 경우 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 URIhttps://gitlab.example.com/users/auth/openid_connect/callback으로 설정합니다.

  2. ID 토큰 활성화.

  3. 앱에 다음 API 권한을 추가합니다:

    • openid
    • offline_access

사용자 정의 정책 구성#

Azure B2C는 사용자 로그인을 위한 비즈니스 로직을 정의하는 두 가지 방법을 제공합니다:

표준 Azure B2C 사용자 흐름은 GitLab이 사용자를 생성하거나 연결하는 데 필요한 OpenID email 클레임을 보내지 않기 때문에 사용자 정의 정책이 필요합니다. 따라서 표준 사용자 흐름은 allow_single_sign_on 또는 auto_link_user 매개변수와 함께 작동하지 않습니다. 표준 Azure B2C 정책으로는 GitLab이 새 계정을 만들거나 이메일 주소를 사용하는 기존 계정에 연결할 수 없습니다.

사용자 흐름과 사용자 정의 정책에서 Azure AD B2C가 토큰과 클레임을 발행하는 방법에 대한 자세한 내용은 사용자 흐름과 사용자 정의 정책클레임 스키마 구성에 대한 Microsoft 설명서를 참조하십시오.

먼저 사용자 정의 정책을 만듭니다.

Microsoft 지침은 사용자 정의 정책 스타터 팩에서 SocialAndLocalAccounts를 사용하지만 LocalAccounts는 로컬 Active Directory 계정에 대해 인증합니다. 정책을 업로드하기 전에 다음을 수행합니다:

  1. email 클레임을 내보내려면 SignUpOrSignin.xml을 수정합니다. 다음 줄을 교체합니다:

    <OutputClaim ClaimTypeReferenceId="email" />
    

    다음으로:

    <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
    
  2. B2C로 OIDC 검색이 작동하려면 OIDC 사양과 호환되는 발급자로 정책을 구성합니다. 토큰 호환성 설정을 참조하십시오. JwtIssuer 아래 TrustFrameworkBase.xml에서 IssuanceClaimPatternAuthorityWithTfp로 설정합니다:

    <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", # 이 매개변수를 변경하지 마십시오
      label: "Azure B2C OIDC", # 로그인 버튼의 선택적 레이블, 기본값은 "Openid Connect"
      args: {
        name: "openid_connect",
        scope: ["openid"],
        response_mode: "query",
        response_type: "id_token",
        issuer:  "https:///tfp//b2c_1a_signup_signin/v2.0/",
        client_auth_method: "query",
        discovery: true,
        send_scope_to_token_endpoint: true,
        pkce: true,
        client_options: {
          identifier: "",
          secret: "",
          redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
        }
      }
    }]
    

Azure B2C 문제 해결#

  • XML 정책 파일에서 yourtenant.onmicrosoft.com, ProxyIdentityExperienceFrameworkAppId, IdentityExperienceFrameworkAppId의 모든 항목이 B2C 테넌트 호스트 이름 및 해당 클라이언트 ID와 일치하는지 확인합니다.

  • https://jwt.ms를 앱의 리디렉션 URI로 추가하고 사용자 정의 정책 테스터를 사용합니다. 페이로드에 사용자의 이메일 액세스와 일치하는 email이 포함되어 있는지 확인합니다.

  • 사용자 정의 정책을 활성화한 후 사용자가 로그인하려고 할 때 Invalid username or password가 표시될 수 있습니다. 이것은 IdentityExperienceFramework 앱의 구성 문제일 수 있습니다. 앱 매니페스트에 다음 설정이 포함되어 있는지 확인하라고 제안하는 이 Microsoft 댓글을 참조하십시오:

    • "accessTokenAcceptedVersion": null
    • "signInAudience": "AzureADMyOrg"

이 구성은 IdentityExperienceFramework 앱을 만들 때 사용되는 Supported account types 설정에 해당합니다.

Keycloak 구성#

GitLab은 HTTPS를 사용하는 OpenID 공급자와 함께 작동합니다. HTTP를 사용하는 Keycloak 서버를 설정할 수 있지만 GitLab은 HTTPS를 사용하는 Keycloak 서버와만 통신할 수 있습니다.

Keycloak을 구성하여 공개 키 알고리즘을 사용하여 토큰에 서명합니다. 예를 들어 HS256 또는 HS358 대신 RSA256 또는 RSA512를 사용합니다. 공개 키 암호화 알고리즘은:

  • 구성하기 더 쉽습니다.
  • 개인 키를 유출하면 심각한 보안 결과를 초래하기 때문에 더 안전합니다.
  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: "",
        secret: "",
        redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
      }
    }
  }
]

대칭 키 알고리즘으로 Keycloak 구성#

Warning

다음 지침은 완전성을 위해 포함되었지만 절대적으로 필요한 경우에만 대칭 키 암호화를 사용하십시오.

대칭 키 암호화를 사용하려면:

  1. Keycloak 데이터베이스에서 시크릿 키를 추출합니다. Keycloak은 웹 인터페이스에서 이 값을 노출하지 않습니다. 웹 인터페이스에서 볼 수 있는 클라이언트 시크릿은 JSON Web Token에 서명하는 데 사용되는 시크릿과 다른 OAuth 2.0 클라이언트 시크릿입니다.

    예를 들어 Keycloak의 백엔드 데이터베이스로 PostgreSQL을 사용하는 경우:

    • 데이터베이스 콘솔에 로그인합니다.

    • 다음 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)에 대한 키. GitLab을 구성하는 데 첫 번째 value를 사용합니다.

  2. value를 표준 base64로 변환합니다. "Invalid signature with HS256 token" 포스트에서 논의된 바와 같이 value는 RFC 4648의 "URL 및 파일 이름 안전 알파벳으로 Base 64 인코딩" 섹션으로 인코딩됩니다. 이것은 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", # 이 매개변수를 변경하지 마십시오
        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: "",
          pkce: true,
          client_options: {
            identifier: "",
            secret: "",
            redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
          }
        }
      }
    ]
    

JSON::JWS::VerificationFailed 오류가 표시되면 잘못된 시크릿을 지정한 것입니다.

Casdoor#

GitLab은 HTTPS를 사용하는 OpenID 공급자와 함께 작동합니다. HTTPS를 사용하여 Casdoor를 통해 OpenID로 GitLab에 연결합니다.

앱에 대해 Casdoor에서 다음 단계를 완료합니다:

  1. 클라이언트 ID와 클라이언트 시크릿을 얻습니다.
  2. GitLab 리디렉션 URL을 추가합니다. 예를 들어 GitLab 도메인이 gitlab.example.com인 경우 Casdoor 앱에 다음 Redirect URI가 있는지 확인합니다: https://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://",
            client_auth_method: "query",
            discovery: true,
            uid_field: "sub",
            client_options: {
                identifier: "",
                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://',
        discovery: true,
        client_auth_method: 'query',
        uid_field: 'sub',
        client_options: {
          identifier: '',
          secret: '',
          redirect_uri: 'https://gitlab.example.com/users/auth/openid_connect/callback'
        }
      }
    }

여러 OpenID Connect 공급자 구성#

여러 OpenID Connect(OIDC) 공급자를 사용하도록 애플리케이션을 구성할 수 있습니다. 이를 위해 구성 파일에서 strategy_class를 명시적으로 설정합니다.

다음 시나리오 중 하나에서 이를 수행해야 합니다:

다음 구성 예시는 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 그룹 구성원 자격을 기반으로 사용자 구성#

OIDC 그룹 구성원 자격을 구성할 수 있습니다:

  • 사용자가 특정 그룹의 구성원이 되도록 요구.
  • 그룹 구성원 자격에 따라 사용자에게 외부, 관리자 또는 감사자 역할 할당.

GitLab은 각 로그인 시 이러한 그룹을 확인하고 필요에 따라 사용자 속성을 업데이트합니다. 이 기능을 사용하면 사용자를 GitLab 그룹에 자동으로 추가할 수 없습니다.

특정 그룹에 정의된 값은 ID 공급자가 반환하는 값을 반영해야 합니다. 예를 들어 Microsoft Entra OIDC는 GroupID를 반환하므로 required_groups 구성은 required_groups: ["55db8574-c392-4e8b-892d-1e086394be9c"]와 같이 표시됩니다.

필수 그룹#

ID 공급자(IdP)는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 사용자가 특정 그룹의 구성원이 되도록 요구하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

외부 그룹#

IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 그룹 구성원 자격을 기반으로 사용자를 외부 사용자로 식별하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

감사자 그룹#

IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 그룹 구성원 자격에 따라 사용자를 감사자로 할당하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

관리자 그룹#

IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용하여 그룹 구성원 자격에 따라 사용자를 관리자로 할당하려면 GitLab을 구성하여 다음을 식별합니다:

  • groups_attribute 설정을 사용하여 OIDC 응답에서 그룹을 찾을 위치.
  • 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"]
            }
          }
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항을 적용하려면 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"]
              }
            }
          }
        }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

ID 토큰에 대한 사용자 정의 기간 구성#

히스토리

기본적으로 GitLab ID 토큰은 120초 후에 만료됩니다.

ID 토큰에 대한 사용자 정의 기간을 구성하려면:

  1. /etc/gitlab/gitlab.rb를 편집합니다:

    gitlab_rails['oidc_provider_openid_id_token_expire_in_seconds'] = 3600
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

  1. /home/git/gitlab/config/gitlab.yml을 편집합니다:

    production: &base
      oidc_provider:
       openid_id_token_expire_in_seconds: 3600
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재구성합니다.

단계적 인증(Step-up authentication)#

Feature flag

이 기능의 가용성은 기능 플래그로 제어됩니다. 자세한 내용은 기록을 참조하십시오. 이 기능은 테스트용으로 사용할 수 있지만 프로덕션 사용에는 준비가 되지 않았습니다.

경우에 따라 기본 인증 방법이 중요한 리소스나 고위험 작업을 보호하지 못합니다. 단계적 인증은 권한 있는 작업이나 민감한 작업에 추가 레이어를 추가합니다. 예를 들어 Admin 영역에 액세스할 때.

단계적 인증을 사용하면 사용자는 특정 기능에 액세스하기 전에 등록된 이중 인증 방법으로 추가 인증을 완료해야 합니다.

OIDC 표준에는 인증 컨텍스트 클래스 참조(ACR)가 포함됩니다. ACR 개념은 Admin 모드와 같은 다양한 시나리오에 대한 단계적 인증을 구성하고 구현하는 데 도움이 됩니다.

이 기능은 실험이며 예고 없이 변경될 수 있습니다. 이 기능은 프로덕션 사용에 준비가 되지 않았습니다. 이 기능을 사용하려면 먼저 프로덕션 외부에서 테스트해야 합니다.

Admin 모드에 단계적 인증 활성화#

히스토리
  • GitLab 17.11에서 omniauth_step_up_auth_for_admin_mode라는 플래그와 함께 도입됨. 기본적으로 비활성화됨.

Admin 모드에 단계적 인증을 활성화하려면:

  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'(Authentication Context Class Reference) 클레임은
                  # 단계적 인증 과제를 통과하기 위해 'gold' 값을 가져야 합니다.
                  # 이를 통해 특정 수준의 인증 보증이 보장됩니다.
                  required: {
                    acr: 'gold'
                  },
                  # `included` 필드도 ID 토큰에 포함되어야 하는 키-값 쌍을 정의합니다.
                  # 배열에 여러 허용 값을 정의할 수 있습니다. 배열이 사용되지 않으면 값이 정확히 일치해야 합니다.
                  # 이 예시에서 'amr'(Authentication Method References) 클레임은
                  # 단계적 인증 과제를 통과하기 위해 'mfa' 또는 'fpt' 값을 가져야 합니다.
                  # 이는 사용자가 추가 인증 요소를 제공해야 하는 시나리오에 유용합니다.
                  included: {
                    amr: ['mfa', 'fpt']
                  },
                },
                # `params` 필드는 인증 프로세스 중에 전송되는 추가 매개변수를 정의합니다.
                # 이 예시에서 `claims` 매개변수는 인증 요청에 추가되어
                # ID 토큰에 'gold' 값으로 'acr' 클레임을 포함하도록 ID 공급자에 지시합니다.
                # 'essential: true'는 이 클레임이 성공적인 인증에 필요함을 나타냅니다.
                params: {
                  claims: {
                    id_token: {
                      acr: {
                        essential: true,
                        values: ['gold']
                      }
                    }
                  }
                },
                # 선택 사항: 단계적 인증에 실패한 사용자를 위한 사용자 정의 설명서 링크 제공
                # 이 링크는 단계적 인증이 실패할 때 표시되어 사용자를 조직별 인증 설명서로 안내합니다.
                documentation_link: 'https://internal.example.com/path/to/documentation'
              },
            }
          }
    
  2. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

Note

OIDC는 표준화되어 있지만 서로 다른 ID 공급자(IdP)는 고유한 요구 사항을 가질 수 있습니다. params 설정은 단계적 인증에 필요한 매개변수를 정의하기 위한 유연한 해시를 허용합니다. 이러한 값은 각 IdP의 요구 사항에 따라 다를 수 있습니다.

Keycloak을 사용한 단계적 인증 요구#

Keycloak은 인증 수준 정의 및 사용자 정의 브라우저 로그인 흐름을 통해 단계적 인증을 지원합니다.

Keycloak을 사용한 Admin 모드에 단계적 인증을 요구하려면:

  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"] # `step_up_auth => admin_mode => params`에 정의된 매개변수와 일치
            },
            step_up_auth: {
              admin_mode: {
                id_token: {
                  # 이 예시에서 'acr' 클레임은 Keycloak 설명서에도 정의된 'gold' 값을 가져야 합니다.
                  required: {
                    acr: 'gold'
                  }
                },
                params: {
                  claims: {
                    id_token: {
                      acr: { essential: true, values: ['gold'] }
                    }
                  },
                },
                # 선택 사항: Keycloak별 단계적 인증 도움말을 위한 사용자 정의 설명서 링크 추가
                documentation_link: 'https://internal.example.com/path/to/documentation'
              },
            }
          }
    
  4. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

Microsoft Entra ID를 사용한 단계적 인증 요구#

Microsoft Entra ID(이전의 Azure Active Directory)는 조건부 액세스 인증 컨텍스트를 통해 단계적 인증을 지원합니다. 올바른 구성을 정의하려면 Microsoft Entra ID 관리자와 협력해야 합니다.

다음 측면을 고려하십시오:

  • 인증 컨텍스트 ID는 다른 ID 공급자에 사용되는 ID 토큰 클레임 acr이 아닌 acrs 클레임을 통해서만 요청됩니다.
  • 인증 컨텍스트 ID는 c1에서 c99까지의 고정 값을 사용하며 각 값은 조건부 액세스 정책이 있는 특정 인증 컨텍스트를 나타냅니다.
  • 기본적으로 Microsoft Entra ID는 ID 토큰에 acrs 클레임을 포함하지 않습니다. 이를 활성화하려면 선택적 클레임 구성을 해야 합니다.
  • 단계적 인증이 성공하면 응답은 acrs 클레임을 문자열의 JSON 배열로 반환합니다. 예를 들어: acrs: ["c1", "c2", "c3"].

Microsoft Entra ID를 사용한 Admin 모드에 단계적 인증을 요구하려면:

  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"] # `step_up_auth => admin_mode => params`에 정의된 매개변수와 일치
          },
          step_up_auth: {
            admin_mode: {
              id_token: {
                # 이 예시에서 Microsoft Entra ID 관리자는 원하는 보안 수준을 가진
                # 인증 컨텍스트 ID로 `c20`을 정의하고 ID 토큰에 포함될 선택적 클레임 `acrs`를 정의했습니다.
                # `included` 필드는 id 토큰 클레임 `acrs`에 `c20` 값이 포함되어야 함을 선언합니다.
                included: {
                  acrs: ["c20"],
                },
              },
              params: {
                claims: {
                  id_token: {
                    acrs: { essential: true, value: 'c20' }
                  }
                },
              },
              # 선택 사항: Microsoft Entra ID 단계적 인증을 위한 사용자 정의 설명서 링크 추가
              documentation_link: 'https://internal.example.com/path/to/documentation'
            },
          }
        }
    
  5. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

그룹에 단계적 인증 공급자 추가#

히스토리
  • GitLab 18.4에서 omniauth_step_up_auth_for_namespace라는 플래그와 함께 도입됨. 기본적으로 비활성화됨.

인스턴스의 모든 그룹에서 사용 가능한 단계적 인증 공급자를 추가할 수도 있습니다. 이렇게 하면 그룹에서 단계적 인증을 강제할 수 없으며 각 그룹은 여전히 설정해야 합니다.

그룹에 단계적 인증 공급자를 추가하려면:

  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 모드에 대한 단계적 인증 구성과 달리 `namespace` 객체를 사용합니다.
              # 이는 Admin 모드만이 아닌 전체 그룹에 대한 액세스에 단계적 인증을 추가하기 때문입니다.
              namespace : {
                # `id_token` 필드는 토큰에 포함되어야 하는 클레임을 정의합니다.
                # `required` 또는 `included` 필드 중 하나 또는 둘 다에 클레임을 지정할 수 있습니다.
                # 토큰은 이러한 필드에 정의하는 모든 클레임에 대해 일치하는 값을 포함해야 합니다.
                id_token: {
                  # `required` 필드는 ID 토큰에 포함되어야 하는 키-값 쌍을 정의합니다.
                  # 값은 정의된 것과 정확히 일치해야 합니다.
                  required: {
                    acr: 'gold'
                  },
                  # `included` 필드도 ID 토큰에 포함되어야 하는 키-값 쌍을 정의합니다.
                  included: {
                    amr: ['mfa', 'fpt']
                  },
                },
                # `params` 필드는 인증 프로세스 중에 전송되는 추가 매개변수를 정의합니다.
                params: {
                  claims: {
                    id_token: {
                      acr: {
                        essential: true,
                        values: ['gold']
                      }
                    }
                  }
                }
              },
            }
          }
    
  2. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

그룹에 단계적 인증 강제#

사용자가 그룹에 액세스하기 전에 단계적 인증을 완료하도록 강제할 수 있습니다. 이 설정은 각 그룹에 대해 개별적으로 관리되지만 이전에 전체 인스턴스에 추가된 단계적 인증 공급자가 필요합니다.

사전 요구 사항:

그룹에 단계적 인증을 강제하려면:

  1. 상단 표시줄에서 Search or go to를 선택하고 그룹을 찾습니다.
  2. Settings > General을 선택합니다.
  3. Permissions and group features 섹션을 확장합니다.
  4. 단계적 인증 아래에서 사용 가능한 인증 공급자를 선택합니다.
  5. Save changes를 선택합니다.

단계적 인증에 사용자 정의 설명서 링크 추가#

단계적 인증이 실패하면 GitLab은 사용자가 조직의 인증 요구 사항을 이해하는 데 도움이 되는 사용자 정의 설명서 링크를 표시할 수 있습니다. 이 기능을 통해 관리자는 내부 설명서나 도움 리소스로 사용자를 안내하는 조직별 지침을 제공할 수 있습니다.

사용자 정의 설명서 링크를 추가하려면:

  1. GitLab 구성 파일(gitlab.yml 또는 /etc/gitlab/gitlab.rb)을 편집하여 step_up_auth => admin_modedocumentation_link 필드를 추가합니다.

    production: &base
      omniauth:
        providers:
        - { name: 'openid_connect',
            label: 'Corporate SSO',
            # ... 다른 공급자 구성 ...
            step_up_auth: {
              admin_mode: {
                # ... id_token 및 params 구성 ...
                documentation_link: 'https://internal.example.com/path/to/documentation'
              }
            }
          }
    
  2. 구성 파일을 저장하고 변경 사항을 적용하려면 GitLab을 재시작합니다.

사용자가 단계적 인증에 실패하면 실패한 공급자에 대한 관련 설명서 링크가 포함된 도움이 되는 오류 메시지가 표시됩니다. 링크는 단계적 인증이 실제로 실패한 공급자에 대해서만 표시되므로 지침이 더 관련성이 높고 실행 가능합니다.

Note

설명서 링크 모범 사례:

  • 보안을 위해 HTTPS URL을 사용합니다.
  • 조직의 특정 인증 요구 사항을 설명하는 내부 설명서로 링크합니다.
  • MFA 또는 다른 필수 인증 방법을 활성화하는 방법에 대한 정보를 포함합니다.

세션 만료 비활성화#

기본적으로 단계적 인증 세션은 ID 공급자(IdP) 토큰 만료 시간(일반적으로 약 10분)에 따라 만료됩니다.

session_expiration_enabled 설정으로 세션 만료를 제어할 수 있습니다:

설정 동작
session_expiration_enabled: true (기본값) 단계적 인증은 IdP 토큰 exp 클레임에 따라 만료됩니다. 일반적으로 약 10분입니다.
session_expiration_enabled: false 단계적 인증은 사용자가 로그아웃할 때까지 전체 사용자 세션 동안 유효합니다.
Warning

세션 만료를 비활성화하면 사용자가 주기적으로 ID를 재확인하는 대신 세션당 한 번만 인증합니다. 보안 요구 사항이 세션 수명 단계적 인증을 허용하는 경우에만 이 설정을 비활성화하십시오.

세션 만료를 비활성화하려면:

  1. /etc/gitlab/gitlab.rb를 편집합니다:

    gitlab_rails['omniauth_providers'] = [
      {
        name: "openid_connect",
        label: "Provider name",
        args: {
          name: "openid_connect",
          # ... 다른 args ...
        },
        step_up_auth: {
          session_expiration_enabled: false,  # 세션 만료 비활성화
          admin_mode: {
            # ... admin_mode 구성 ...
          },
          namespace: {
            # ... namespace 구성 ...
          }
        }
      }
    ]
    
  2. 파일을 저장하고 GitLab을 재구성합니다:

    sudo gitlab-ctl reconfigure
    
  1. config/gitlab.yml을 편집합니다:

    production: &base
      omniauth:
        providers:
          - { name: 'openid_connect',
              label: 'Provider name',
              args: {
                name: 'openid_connect',
                # ... 다른 args ...
              },
              step_up_auth: {
                session_expiration_enabled: false,
                admin_mode: {
                  # ... admin_mode 구성 ...
                },
                namespace: {
                  # ... namespace 구성 ...
                }
              }
            }
    
  2. 파일을 저장하고 GitLab을 재시작합니다:

    # systemd를 실행하는 시스템의 경우
    sudo systemctl restart gitlab.target
    
    # SysV init을 실행하는 시스템의 경우
    sudo service gitlab restart
    

문제 해결#

  1. discoverytrue로 설정되어 있는지 확인합니다. false로 설정하면 OpenID가 작동하는 데 필요한 모든 URL과 키를 지정해야 합니다.
  2. 시스템 시계를 확인하여 시간이 올바르게 동기화되었는지 확인합니다.
  3. OmniAuth OpenID Connect 설명서에 언급된 것처럼 issuer가 검색 URL의 기본 URL에 해당하는지 확인합니다. 예를 들어 https://accounts.google.com은 URL https://accounts.google.com/.well-known/openid-configuration에 사용됩니다.
  4. OpenID Connect 클라이언트는 client_auth_method가 정의되지 않았거나 basic으로 설정된 경우 HTTP Basic 인증을 사용하여 OAuth 2.0 액세스 토큰을 전송합니다. userinfo 엔드포인트를 검색할 때 401 오류가 표시되면 OpenID 웹 서버 구성을 확인합니다. 예를 들어 oauth2-server-php의 경우 Apache에 구성 매개변수를 추가해야 할 수 있습니다.
  5. 단계적 인증 전용: step_up_auth => admin_mode => params에 정의된 모든 매개변수가 args => allow_authorize_params에도 정의되어 있는지 확인합니다. 여기에는 IdP 인증 엔드포인트로 리디렉션하는 데 사용되는 요청 쿼리 매개변수의 매개변수가 포함됩니다.