OpenID Connect를 인증 공급자로 사용
GitLab v19.4Offering: GitLab Self-Managed
요약
GitLab을 OpenID Connect를 사용하는 OmniAuth 공급자의 클라이언트 애플리케이션으로 사용할 수 있습니다. OpenID Connect OmniAuth 공급자를 활성화하려면 OpenID Connect 공급자에 애플리케이션을 등록해야 합니다.
GitLab을 OpenID Connect를 사용하는 OmniAuth 공급자의 클라이언트 애플리케이션으로 사용할 수 있습니다.
OpenID Connect OmniAuth 공급자를 활성화하려면 OpenID Connect 공급자에 애플리케이션을 등록해야 합니다. OpenID Connect 공급자는 사용자가 사용할 클라이언트 정보와 시크릿을 제공합니다.
-
GitLab 서버에서 구성 파일을 엽니다.
Linux 패키지 설치의 경우:
sudo editor /etc/gitlab/gitlab.rb자체 컴파일 설치의 경우:
cd /home/git/gitlab sudo -u git -H editor config/gitlab.yml -
공통 설정을 구성하여
openid_connect를 싱글 사인온 공급자로 추가합니다. 이렇게 하면 기존 GitLab 계정이 없는 사용자에게 Just-In-Time 계정 프로비저닝이 활성화됩니다. -
공급자 구성을 추가합니다.
Linux 패키지 설치의 경우:
gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", # do not change this parameter label: "Provider name", # optional label for login button, defaults to "Openid Connect" icon: "<custom_provider_icon>", args: { name: "openid_connect", scope: ["openid","profile","email"], response_type: "code", issuer: "<your_oidc_url>", discovery: true, client_auth_method: "query", uid_field: "<uid_field>", send_scope_to_token_endpoint: "false", pkce: true, client_options: { identifier: "<your_oidc_client_id>", secret: "<your_oidc_client_secret>", redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback" } } } ]여러 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', # do not change this parameter label: 'Provider name', # optional label for login button, defaults to "Openid Connect" icon: '<custom_provider_icon>', args: { name: 'openid_connect', scope: ['openid','profile','email'], response_type: 'code', issuer: '<your_oidc_url>', discovery: true, client_auth_method: 'query', uid_field: '<uid_field>', send_scope_to_token_endpoint: false, pkce: true, client_options: { identifier: '<your_oidc_client_id>', secret: '<your_oidc_client_secret>', redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback' } } }[!note] 각 구성 옵션에 대한 자세한 내용은 OmniAuth OpenID Connect 사용 문서와 OpenID Connect Core 1.0 사양을 참고합니다.
-
공급자 구성에서 공급자의 값을 사용 중인 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). 이 값을 제공하지 않으면client_options의 값으로 URL을 만들며, 형식은<client_options.scheme>://<client_options.host>:<client_options.port>입니다.discovery를true로 설정하면 OpenID Connect 공급자가 자동으로<your_oidc_url>/.well-known/openid-configuration을 사용해 클라이언트 옵션을 검색하려고 시도합니다. 기본값은false입니다.client_auth_method(선택 사항)는 OpenID Connect 공급자에 대해 클라이언트를 인증하는 방법을 지정합니다.- 지원되는 값은 다음과 같습니다.
basic- HTTP Basic 인증.jwt_bearer- JWT 기반 인증(개인 키 및 클라이언트 시크릿 서명).mtls- 상호 TLS 또는 X.509 인증서 검증.- 그 외의 값은 클라이언트 ID와 시크릿을 요청 본문에 담아 전송합니다.
- 지정하지 않으면 기본값은
basic입니다.
- 지원되는 값은 다음과 같습니다.
<uid_field>(선택 사항)는uid의 값을 정의하는user_info.raw_attributes의 필드 이름입니다(예:preferred_username). 이 값을 제공하지 않거나 구성된 값의 필드가user_info.raw_attributes세부 정보에 없으면uid는sub필드를 사용합니다.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입니다.
-
구성 파일을 저장합니다.
-
변경 사항을 적용하려면 다음과 같이 합니다.
- Linux 패키지로 GitLab을 설치했다면 GitLab을 재구성합니다.
- GitLab을 자체 컴파일하여 설치했다면 GitLab을 다시 시작합니다.
로그인 페이지의 일반 로그인 양식 아래에 OpenID Connect 옵션이 표시됩니다. 이 옵션을 선택하면 인증 절차가 시작됩니다. 클라이언트에서 확인이 필요한 경우 OpenID Connect 공급자가 로그인과 GitLab 애플리케이션 인가를 요청합니다. 이후 GitLab으로 리디렉션되어 로그인됩니다.
구성 예시#
다음 구성은 Linux 패키지 설치를 사용할 때 여러 공급자와 함께 OpenID를 설정하는 방법을 보여 줍니다.
Google 구성#
자세한 내용은 Google 문서를 참고합니다.
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect", # do not change this parameter
label: "Google OpenID", # optional label for login button, defaults to "Openid Connect"
args: {
name: "openid_connect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://accounts.google.com",
client_auth_method: "query",
discovery: true,
uid_field: "preferred_username",
pkce: true,
client_options: {
identifier: "",
secret: "",
redirect_uri: "https://example.com/users/auth/openid_connect/callback",
}
}
}
]
Microsoft Azure 구성#
Microsoft Azure의 OpenID Connect(OIDC) 프로토콜은 Microsoft ID 플랫폼(v2) 엔드포인트를 사용합니다. 시작하려면 Azure Portal에 로그인합니다. 앱에는 다음 정보가 필요합니다.
- 테넌트 ID. 이미 가지고 있을 수 있습니다. 자세한 내용은 Microsoft Azure 테넌트 문서를 참고합니다.
- 클라이언트 ID와 클라이언트 시크릿. 앱의 테넌트 ID, 클라이언트 ID, 클라이언트 시크릿을 얻으려면 Microsoft 빠른 시작: 애플리케이션 등록 문서의 지침을 따릅니다.
Microsoft Azure 애플리케이션을 등록할 때 GitLab이 필요한 세부 정보를 가져올 수 있도록 API 권한을 부여해야 합니다.
최소한 openid, profile, email 권한을 제공해야 합니다.
자세한 내용은 웹 API용 앱 권한 구성에 관한 Microsoft 문서를 참고합니다.
Azure에서 프로비저닝하는 모든 계정에는 이메일 주소가 정의되어 있어야 합니다. 이메일 주소가 정의되지 않은 경우 Azure는 무작위로 생성된 주소를 할당합니다. 신규 사용자에 대한 도메인 제한을 구성한 경우, 이 무작위 주소 때문에 계정이 생성되지 않을 수 있습니다.
Linux 패키지 설치의 예시 구성 블록입니다.
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect", # do not change this parameter
label: "Azure OIDC", # optional label for login button, defaults to "Openid Connect"
args: {
name: "openid_connect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://login.microsoftonline.com//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 Discovery를 비활성화합니다.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", # do not change this parameter
label: "Azure OIDC", # optional label for login button, defaults to "Openid Connect"
args: {
name: "openid_connect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://login.microsoftonline.com//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 쿼리 매개변수가 누락되었거나 잘못되었을 가능성이 높습니다.
Microsoft가 반환한 ID 토큰을
jwks_uri 엔드포인트가 제공하는 키로 검증할 수 없으면 GitLab이 해당 오류를
발생시킵니다.
자세한 내용은 토큰 검증에 관한 Microsoft Entra 문서를 참고합니다.
일반 OpenID Connect 구성으로 마이그레이션#
azure_activedirectory_v2와 azure_oauth2 모두에서 일반 OpenID Connect 구성으로 마이그레이션할 수 있습니다.
먼저 uid_field를 설정합니다. uid_field와 uid_field로 선택할 수 있는 sub 클레임은 모두 공급자에 따라 다릅니다. uid_field를 설정하지 않고 로그인하면 GitLab에 추가 ID가 생성되며, 이를 수동으로 수정해야 합니다.
| 공급자 | uid_field |
지원 정보 |
|---|---|---|
omniauth-azure-activedirectory-v2 |
oid |
마이그레이션할 때 oid를 uid_field로 구성해야 합니다. |
omniauth_openid_connect |
sub |
다른 필드를 사용하려면 uid_field를 지정합니다. |
일반 OpenID Connect 구성으로 마이그레이션하려면 구성을 업데이트해야 합니다.
Linux 패키지 설치의 경우 다음과 같이 구성을 업데이트합니다.
gitlab_rails['omniauth_providers'] = [
{
name: "azure_oauth2",
label: "Azure OIDC", # optional label for login button, defaults to "Openid Connect"
args: {
name: "azure_oauth2", # this matches the existing azure_oauth2 provider name, and only the strategy_class immediately below configures OpenID Connect
strategy_class: "OmniAuth::Strategies::OpenIDConnect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://login.microsoftonline.com//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", # optional label for login button, defaults to "Openid Connect"
args: {
name: "azure_activedirectory_v2",
strategy_class: "OmniAuth::Strategies::OpenIDConnect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://login.microsoftonline.com//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"
}
}
}
azure_oauth2에서 omniauth_openid_connect로 마이그레이션하면서 GitLab 17.0 이상으로 업그레이드하는 경우, 조직에 설정된 sub 클레임 값이 다를 수 있습니다. azure_oauth2는 Microsoft V1 엔드포인트를 사용하고, azure_activedirectory_v2와 omniauth_openid_connect는 공통 sub 값을 가진 Microsoft V2 엔드포인트를 사용합니다.
- Entra ID에 이메일 주소가 있는 사용자의 경우, 이메일 주소로 대체하고 사용자의 ID를 업데이트하려면
다음 방법 중 하나를 사용합니다.
- 자동 연결을 활성화합니다. Linux 패키지 설치에서는
omniauth_auto_link_user를 구성합니다. Helm 설치에서는autoLinkUser를 구성합니다. - 안내형 연결 흐름을 사용합니다. 이 흐름에서는 사용자가 연결하기 전에 기존 자격 증명으로 로그인하여 소유권을 확인하도록 안내합니다. 자세한 내용은 OmniAuth로 로그인할 때 기존 계정 연결을 참고합니다.
- 자동 연결을 활성화합니다. Linux 패키지 설치에서는
- 이메일 주소가 없는 사용자의 경우 관리자는 다음 중 하나를 수행해야 합니다.
- 다른 인증 방법을 설정하거나 GitLab 사용자 이름과 비밀번호를 사용한 로그인을 활성화합니다. 그러면 사용자가 로그인한 후 프로필에서 Azure ID를 수동으로 연결할 수 있습니다.
- 기존
azure_oauth2와 함께 OpenID Connect를 새 공급자로 구현하여, 사용자가 OAuth 2.0으로 로그인하고 OpenID Connect ID를 연결할 수 있게 합니다(이전 방법과 유사).auto_link_user가 활성화되어 있으면 이 방법은 이메일 주소가 있는 사용자에게도 작동합니다. extern_uid를 수동으로 업데이트합니다. 이를 위해 API 또는 Rails 콘솔을 사용하여 각 사용자의extern_uid를 업데이트합니다. 인스턴스가 이미 17.0 이상으로 업그레이드되었고 사용자가 로그인을 시도한 경우 이 방법이 필요할 수 있습니다.
azure_oauth2는 GitLab 계정을 프로비저닝할 때 email 클레임이 없거나 비어 있으면 Entra ID의 upn 클레임을 이메일 주소로 사용했을 수 있습니다.
Configure Microsoft Azure Active Directory B2C#
Azure Active Directory B2C와 함께 작동하려면 GitLab에 특별한 구성이 필요합니다. 시작하려면 Azure Portal에 로그인합니다. 앱에 대해 Azure에서 다음 정보가 필요합니다.
- 테넌트 ID. 이미 가지고 있을 수 있습니다. 자세한 내용은 Microsoft Azure 테넌트 문서를 검토합니다.
- 클라이언트 ID와 클라이언트 시크릿. 앱의 클라이언트 ID와 클라이언트 시크릿을 얻으려면 Microsoft 튜토리얼 문서의 지침을 따릅니다.
- 사용자 흐름 또는 정책 이름. Microsoft 튜토리얼의 지침을 따릅니다.
앱을 구성합니다.
-
앱
Redirect URI를 설정합니다. 예를 들어 GitLab 도메인이gitlab.example.com이면 앱Redirect URI를 다음 값으로 설정합니다.https://gitlab.example.com/users/auth/openid_connect/callback. -
ID 토큰을 활성화합니다.
-
앱에 다음 API 권한을 추가합니다.
openidoffline_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 계정에 대해 인증합니다. 정책을 업로드하기 전에 다음을 수행합니다.
-
email클레임을 내보내려면SignUpOrSignin.xml을 수정합니다. 다음 줄을 바꿉니다.<OutputClaim ClaimTypeReferenceId="email" />다음으로 바꿉니다.
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" /> -
B2C에서 OIDC 검색이 작동하려면 정책을 발급자와 함께 구성해야 하며, 이 발급자는 OIDC 사양과 호환되어야 합니다. 토큰 호환성 설정을 참고합니다.
TrustFrameworkBase.xml의JwtIssuer아래에서IssuanceClaimPattern을AuthorityWithTfp로 설정합니다.<ClaimsProvider> <DisplayName>Token Issuer</DisplayName> <TechnicalProfiles> <TechnicalProfile Id="JwtIssuer"> <DisplayName>JWT Issuer</DisplayName> <Protocol Name="None" /> <OutputTokenFormat>JWT</OutputTokenFormat> <Metadata> <Item Key="IssuanceClaimPattern">AuthorityWithTfp</Item> ... -
정책을 업로드합니다. 기존 정책을 업데이트하는 경우 기존 파일을 덮어씁니다.
-
발급자 URL을 확인하려면 로그인 정책을 사용합니다. 발급자 URL의 형식은 다음과 같습니다.
https://<YOUR-DOMAIN>/tfp/<YOUR-TENANT-ID>/<YOUR-SIGN-IN-POLICY-NAME>/v2.0/URL에서 정책 이름은 소문자입니다. 예를 들어
B2C_1A_signup_signin정책은b2c_1a_signup_signin으로 표시됩니다.끝의 슬래시를 반드시 포함합니다.
-
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예를 들어
domain이example.b2clogin.com이고 테넌트 ID가fc40c736-476c-4da1-b489-ee48cee84386이면curl과jq를 사용해 발급자를 추출할 수 있습니다.$ 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/" -
signup_signin에 사용하는 사용자 정의 정책으로 발급자 URL을 구성합니다. 다음은 Linux 패키지 설치에서b2c_1a_signup_signin사용자 정의 정책을 사용하는 구성입니다.gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", # do not change this parameter label: "Azure B2C OIDC", # optional label for login button, defaults to "Openid Connect" args: { name: "openid_connect", scope: ["openid"], response_mode: "query", response_type: "id_token", issuer: "https:///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 문제 해결#
-
yourtenant.onmicrosoft.com,ProxyIdentityExperienceFrameworkAppId,IdentityExperienceFrameworkAppId가 모두 B2C 테넌트 호스트 이름 및 XML 정책 파일의 각 클라이언트 ID와 일치하는지 확인합니다. -
앱에 리디렉션 URI로
https://jwt.ms를 추가하고 사용자 정의 정책 테스터를 사용합니다. 페이로드에 사용자의 이메일 액세스와 일치하는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를 사용합니다. 공개 키 암호화 알고리즘은 다음과 같은 장점이 있습니다.
- 구성이 더 쉽습니다.
- 개인 키 유출이 심각한 보안 문제로 이어지므로 더 안전합니다.
- Keycloak 관리 콘솔을 엽니다.
- Realm Settings > Tokens > Default Signature Algorithm을 선택합니다.
- 서명 알고리즘을 구성합니다.
Linux 패키지 설치의 예시 구성 블록입니다.
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect", # do not change this parameter
label: "Keycloak", # optional label for login button, defaults to "Openid Connect"
args: {
name: "openid_connect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://keycloak.example.com/realms/myrealm",
client_auth_method: "query",
discovery: true,
uid_field: "preferred_username",
pkce: true,
client_options: {
identifier: "",
secret: "",
redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback"
}
}
}
]
대칭 키 알고리즘으로 Keycloak 구성#
다음 지침은 완전성을 위해 포함되었으며, 대칭 키 암호화는 꼭 필요한 경우에만 사용합니다.
대칭 키 암호화를 사용하려면 다음과 같이 합니다.
-
Keycloak 데이터베이스에서 시크릿 키를 추출합니다. Keycloak은 이 값을 웹 인터페이스에 노출하지 않습니다. 웹 인터페이스에 표시되는 클라이언트 시크릿은 OAuth 2.0 클라이언트 시크릿이며, JSON Web Token 서명에 사용하는 시크릿과는 다릅니다.
예를 들어 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) 하나입니다. 첫 번째value를 사용해 GitLab을 구성합니다.
-
-
value를 표준 base64로 변환합니다. "Invalid signature with HS256 token" 게시글에서 설명하듯이value는 RFC 4648의 "Base 64 Encoding with URL and Filename Safe Alphabet" 절로 인코딩되어 있습니다. 이를 RFC 2045에서 정의한 표준 base64로 변환해야 합니다. 다음 Ruby 스크립트로 변환할 수 있습니다.require 'base64' value = "lo6cqjD6Ika8pk7qc3fpFx9ysrhf7E62-sqGc8drp3XW-wr93zru8PFsQokHZZuJJbaUXvmiOftCZM3C4KW3-g" Base64.encode64(Base64.urlsafe_decode64(value))결과 값은 다음과 같습니다.
lo6cqjD6Ika8pk7qc3fpFx9ysrhf7E62+sqGc8drp3XW+wr93zru8PFsQokH\nZZuJJbaUXvmiOftCZM3C4KW3+g==\n -
이 base64 인코딩 시크릿을
jwt_secret_base64에 지정합니다. 예를 들면 다음과 같습니다.gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", # do not change this parameter label: "Keycloak", # optional label for login button, defaults to "Openid Connect" args: { name: "openid_connect", scope: ["openid", "profile", "email"], response_type: "code", issuer: "https://keycloak.example.com/auth/realms/myrealm", client_auth_method: "query", discovery: true, uid_field: "preferred_username", jwt_secret_base64: "", pkce: true, client_options: { identifier: "", secret: "", redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback" } } } ]
JSON::JWS::VerificationFailed 오류가 표시되면
잘못된 시크릿을 지정한 것입니다.
Casdoor#
GitLab은 HTTPS를 사용하는 OpenID 공급자와 함께 작동합니다. Casdoor와 OpenID를 통해 GitLab에 연결하려면 HTTPS를 사용합니다.
앱에 대해 Casdoor에서 다음 단계를 완료합니다.
- 클라이언트 ID와 클라이언트 시크릿을 가져옵니다.
- 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", # do not change this parameter
label: "Casdoor", # optional label for login button, defaults to "Openid Connect"
args: {
name: "openid_connect",
scope: ["openid", "profile", "email"],
response_type: "code",
issuer: "https://",
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', # do not change this parameter
label: 'Casdoor', # optional label for login button, defaults to "Openid Connect"
args: {
name: 'openid_connect',
scope: ['openid', 'profile', 'email'],
response_type: 'code',
issuer: 'https://',
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를 명시적으로 설정하면 됩니다.
다음 중 하나에 해당하는 경우 이렇게 구성하는 것이 좋습니다.
- OpenID Connect 프로토콜로 마이그레이션하는 경우.
- 서로 다른 수준의 인증을 제공하는 경우.
다음 예시 구성은 2FA가 있는 옵션과 2FA가 없는 옵션으로 서로 다른 수준의 인증을 제공하는 방법을 보여 줍니다.
Linux 패키지 설치의 경우:
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
label: "Provider name", # optional label for login button, defaults to "Openid Connect"
icon: "<custom_provider_icon>",
args: {
name: "openid_connect",
strategy_class: "OmniAuth::Strategies::OpenIDConnect",
scope: ["openid","profile","email"],
response_type: "code",
issuer: "<your_oidc_url>",
discovery: true,
client_auth_method: "query",
uid_field: "<uid_field>",
send_scope_to_token_endpoint: "false",
pkce: true,
client_options: {
identifier: "<your_oidc_client_id>",
secret: "<your_oidc_client_secret>",
redirect_uri: "<your_gitlab_url>/users/auth/openid_connect/callback"
}
}
},
{
name: "openid_connect_2fa",
label: "Provider name 2FA", # optional label for login button, defaults to "Openid Connect"
icon: "<custom_provider_icon>",
args: {
name: "openid_connect_2fa",
strategy_class: "OmniAuth::Strategies::OpenIDConnect",
scope: ["openid","profile","email"],
response_type: "code",
issuer: "<your_oidc_url>",
discovery: true,
client_auth_method: "query",
uid_field: "<uid_field>",
send_scope_to_token_endpoint: "false",
pkce: true,
client_options: {
identifier: "<your_oidc_client_id>",
secret: "<your_oidc_client_secret>",
redirect_uri: "<your_gitlab_url>/users/auth/openid_connect_2fa/callback"
}
}
}
]
자체 컴파일 설치의 경우:
- { name: 'openid_connect',
label: 'Provider name', # optional label for login button, defaults to "Openid Connect"
icon: '<custom_provider_icon>',
args: {
name: 'openid_connect',
strategy_class: "OmniAuth::Strategies::OpenIDConnect",
scope: ['openid', 'profile', 'email'],
response_type: 'code',
issuer: '<your_oidc_url>',
discovery: true,
client_auth_method: 'query',
uid_field: '<uid_field>',
send_scope_to_token_endpoint: false,
pkce: true,
client_options: {
identifier: '<your_oidc_client_id>',
secret: '<your_oidc_client_secret>',
redirect_uri: '<your_gitlab_url>/users/auth/openid_connect/callback'
}
}
}
- { name: 'openid_connect_2fa',
label: 'Provider name 2FA', # optional label for login button, defaults to "Openid Connect"
icon: '<custom_provider_icon>',
args: {
name: 'openid_connect_2fa',
strategy_class: "OmniAuth::Strategies::OpenIDConnect",
scope: ['openid', 'profile', 'email'],
response_type: 'code',
issuer: '<your_oidc_url>',
discovery: true,
client_auth_method: 'query',
uid_field: '<uid_field>',
send_scope_to_token_endpoint: false,
pkce: true,
client_options: {
identifier: '<your_oidc_client_id>',
secret: '<your_oidc_client_secret>',
redirect_uri: '<your_gitlab_url>/users/auth/openid_connect_2fa/callback'
}
}
}
이 사용 사례에서는 여러 공급자에 걸쳐 extern_uid를
기업 디렉터리에 이미 알려진 식별자를 기준으로
동기화해야 할 수 있습니다.
이렇게 하려면 uid_field를 설정합니다. 다음 예시 코드는
그 방법을 보여 줍니다.
def sync_missing_provider(self, user: User, extern_uid: str)
existing_identities = []
for identity in user.identities:
existing_identities.append(identity.get("provider"))
local_extern_uid = extern_uid.lower()
for provider in ("openid_connect_2fa", "openid_connect"):
identity = [
identity
for identity in user.identities
if identity.get("provider") == provider
and identity.get("extern_uid").lower() != local_extern_uid
]
if provider not in existing_identities or identity:
if identity and identity[0].get("extern_uid") != "":
logger.error(f"Found different identity for provider {provider} for user {user.id}")
continue
else:
logger.info(f"Add identity 'provider': {provider}, 'extern_uid': {extern_uid} for user {user.id}")
user.provider = provider
user.extern_uid = extern_uid
user = self.save_user(user)
return user
자세한 내용은 GitLab API 사용자 메서드 문서를 참고합니다.
OIDC 그룹 구성원 자격을 기반으로 사용자 구성#
OIDC 그룹 구성원 자격을 다음과 같이 구성할 수 있습니다.
GitLab은 로그인할 때마다 이 그룹을 확인하고 필요에 따라 사용자 속성을 업데이트합니다. 이 기능으로는 사용자를 GitLab 그룹에 자동으로 추가할 수 없습니다.
특정 그룹에 정의한 값은 ID 공급자가 반환하는 값과 같아야 합니다.
예를 들어 Microsoft Entra OIDC는 GroupID를 반환하므로 required_groups 구성은 required_groups: ["55db8574-c392-4e8b-892d-1e086394be9c"]처럼 됩니다.
필수 그룹#
ID 공급자(IdP)는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용해 사용자가 특정 그룹의 구성원이어야 하도록 요구하려면 GitLab이 다음을 식별하도록 구성합니다.
- OIDC 응답에서 그룹을 찾을 위치.
groups_attribute설정을 사용합니다. - 로그인에 필요한 그룹 구성원 자격.
required_groups설정을 사용합니다.
required_groups를 설정하지 않거나 비워 두면 IdP가 OIDC로 인증한 모든 사용자가 GitLab을 사용할 수 있습니다.
-
/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"] } } } } ] -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
-
/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"] } } } } -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
외부 그룹#
IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용해 그룹 구성원 자격에 따라 사용자를 외부 사용자로 식별하려면 GitLab이 다음을 식별하도록 구성합니다.
- OIDC 응답에서 그룹을 찾을 위치.
groups_attribute설정을 사용합니다. - 사용자를 외부 사용자로 식별할 그룹 구성원 자격.
external_groups설정을 사용합니다.
-
/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"] } } } } ] -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
-
/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"] } } } } -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
감사자 그룹#
IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용해 그룹 구성원 자격에 따라 사용자를 감사자로 지정하려면 GitLab이 다음을 식별하도록 구성합니다.
- OIDC 응답에서 그룹을 찾을 위치.
groups_attribute설정을 사용합니다. - 사용자에게 감사자 액세스를 부여할 그룹 구성원 자격.
auditor_groups설정을 사용합니다.
-
/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"] } } } } ] -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
-
/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"] } } } } -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
관리자 그룹#
IdP는 OIDC 응답에서 GitLab으로 그룹 정보를 전달해야 합니다. 이 응답을 사용해 그룹 구성원 자격에 따라 사용자를 관리자로 지정하려면 GitLab이 다음을 식별하도록 구성합니다.
- OIDC 응답에서 그룹을 찾을 위치.
groups_attribute설정을 사용합니다. - 사용자에게 관리자 액세스를 부여할 그룹 구성원 자격.
admin_groups설정을 사용합니다.
-
/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"] } } } } ] -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
-
/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"] } } } } -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
ID 토큰에 대한 사용자 정의 기간 구성#
히스토리
- GitLab 17.8에서 도입되었습니다.
기본적으로 GitLab ID 토큰은 120초 후에 만료됩니다.
ID 토큰에 사용자 정의 기간을 구성하려면 다음과 같이 합니다.
-
/etc/gitlab/gitlab.rb를 편집합니다.gitlab_rails['oidc_provider_openid_id_token_expire_in_seconds'] = 3600 -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
-
/home/git/gitlab/config/gitlab.yml을 편집합니다.production: &base oidc_provider: openid_id_token_expire_in_seconds: 3600 -
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
단계적 인증(Step-up authentication)#
이 기능의 사용 가능 여부는 기능 플래그로 제어됩니다. 자세한 내용은 히스토리를 참고합니다. 이 기능은 테스트할 수 있지만 프로덕션 사용에는 아직 준비되지 않았습니다.
경우에 따라 기본 인증 방법으로는 중요한 리소스나 위험도가 높은 작업을 보호하지 못합니다. 단계적 인증은 권한이 필요한 작업이나 민감한 작업에 추가 보호 계층을 더합니다. 예를 들어 Admin 영역에 액세스하는 경우가 있습니다.
단계적 인증을 사용하면 사용자는 특정 기능에 액세스하기 전에 등록한 2단계 인증 방법으로 추가 인증을 완료해야 합니다.
OIDC 표준에는 인증 컨텍스트 클래스 참조(ACR)가 포함됩니다. ACR 개념은
Admin Mode 같은 다양한 시나리오에서 단계적 인증을 구성하고 구현하는 데 도움이 됩니다.
이 기능은 실험 기능이며 예고 없이 변경될 수 있습니다. 이 기능은 프로덕션 사용에 적합하지 않습니다. 이 기능을 사용하려면 먼저 프로덕션 외 환경에서 테스트해야 합니다.
Admin 모드에 단계적 인증 활성화#
Admin Mode에 단계적 인증을 활성화하려면 다음과 같이 합니다.
-
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"], # Match this to the parameters defined in `step_up_auth => admin_mode => params` }, step_up_auth: { admin_mode: { # The `id_token` field defines the claims that must be included with the token. # You can specify claims in one or both of the `required` or `included` fields. # The token must include matching values for every claim you define in these fields. id_token: { # The `required` field defines key-value pairs that must be included with the ID token. # The values must match exactly what is defined. # In this example, the 'acr' (Authentication Context Class Reference) claim # must have the value 'gold' to pass the step-up authentication challenge. # This ensures a specific level of authentication assurance. required: { acr: 'gold' }, # The `included` field also defines key-value pairs that must be included with the ID token. # Multiple accepted values can be defined in an array. If an array is not used, the value must match exactly. # In this example, the 'amr' (Authentication Method References) claim # must have a value of either 'mfa' or 'fpt' to pass the step-up authentication challenge. # This is useful for scenarios where the user must provide additional authentication factors. included: { amr: ['mfa', 'fpt'] }, }, # The `params` field defines any additional parameters that are sent during the authentication process. # In this example, the `claims` parameter is added to the authorization request and instructs the # identity provider to include an 'acr' claim with the value 'gold' in the ID token. # The 'essential: true' indicates that this claim is required for successful authentication. params: { claims: { id_token: { acr: { essential: true, values: ['gold'] } } } }, # Optional: Provide a custom documentation link for users who fail step-up authentication # This link is displayed when step-up authentication fails, directing users to # organization-specific authentication documentation. documentation_link: 'https://internal.example.com/path/to/documentation' }, } } -
구성 파일을 저장하고 GitLab을 다시 시작하여 변경 사항을 적용합니다.
OIDC는 표준화되어 있지만 ID 공급자(IdP)마다 고유한 요구 사항이 있을 수 있습니다.
params설정은 단계적 인증에 필요한 매개변수를 정의하는 유연한 해시를 허용합니다. 이 값은 각 IdP의 요구 사항에 따라 다를 수 있습니다.
Keycloak으로 단계적 인증 요구#
Keycloak은 인증 수준과 사용자 정의 브라우저 로그인 흐름을 정의하여 단계적 인증을 지원합니다.
Keycloak으로 Admin Mode에 단계적 인증을 요구하려면 다음과 같이 합니다.
-
GitLab에서 Keycloak을 구성합니다.
-
Keycloak 문서의 단계에 따라 Keycloak에서 단계적 인증이 포함된 브라우저 로그인 흐름을 생성합니다.
-
GitLab 구성 파일(
gitlab.yml또는/etc/gitlab/gitlab.rb)을 편집하여 Keycloak OIDC 공급자 구성에서 단계적 인증을 활성화합니다.Keycloak은
silver와gold라는 두 가지 인증 수준을 정의합니다. 다음 예시에서는gold를 높은 보안 수준으로 사용합니다.production: &base omniauth: providers: - { name: 'openid_connect', label: 'Keycloak', args: { name: 'openid_connect', # ... allow_authorize_params: ["claims"] # Match this to the parameters defined in `step_up_auth => admin_mode => params` }, step_up_auth: { admin_mode: { id_token: { # In this example, the 'acr' claim must have the value 'gold' that is also defined in the Keycloak documentation. required: { acr: 'gold' } }, params: { claims: { id_token: { acr: { essential: true, values: ['gold'] } } }, }, # Optional: Add a custom documentation link for Keycloak-specific step-up authentication help documentation_link: 'https://internal.example.com/path/to/documentation' }, } } -
구성 파일을 저장하고 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 Mode에 단계적 인증을 요구하려면 다음과 같이 합니다.
-
GitLab에서 Microsoft Entra ID를 구성합니다.
-
Microsoft Entra ID 문서의 단계에 따라 Microsoft Entra ID에서 조건부 액세스 인증 컨텍스트를 정의합니다.
-
Microsoft Entra ID에서 ID 토큰에 포함할 선택적 클레임
acrs를 정의합니다. -
GitLab 구성 파일(
gitlab.yml또는/etc/gitlab/gitlab.rb)을 편집하여 Microsoft Entra ID 공급자 구성에서 단계적 인증을 활성화합니다.production: &base omniauth: providers: - { name: 'openid_connect', label: 'Azure OIDC', args: { name: 'openid_connect', # ... allow_authorize_params: ["claims"] # Match this to the parameters defined in `step_up_auth => admin_mode => params` }, step_up_auth: { admin_mode: { id_token: { # In this example, the Microsoft Entra ID administrators have defined `c20` # as the authentication context ID with the desired security level and # an optional claim `acrs` to be included in the ID token. # The `included` field declares that the id token claim `acrs` must include the value `c20`. included: { acrs: ["c20"], }, }, params: { claims: { id_token: { acrs: { essential: true, value: 'c20' } } }, }, # Optional: Add a custom documentation link for Microsoft Entra ID step-up authentication documentation_link: 'https://internal.example.com/path/to/documentation' }, } } -
구성 파일을 저장하고 GitLab을 다시 시작하여 변경 사항을 적용합니다.
그룹에 단계적 인증 공급자 추가#
인스턴스의 모든 그룹에서 사용할 수 있는 단계적 인증 공급자를 추가할 수도 있습니다. 이렇게 해도 그룹이 단계적 인증을 사용하도록 강제되지는 않으며, 각 그룹이 이 기능을 개별적으로 설정해야 합니다.
그룹에 단계적 인증 공급자를 추가하려면 다음과 같이 합니다.
-
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"], # Match this to the parameters defined in `step_up_auth => admin_mode => params` }, step_up_auth: { # Unlike step-up authentication configuration for Admin Mode, you use the `namespace` # object. This is because you're adding step-up authentication to access the entire # group, not just Admin Mode. namespace : { # The `id_token` field defines the claims that must be included with the token. # You can specify claims in one or both of the `required` or `included` fields. # The token must include matching values for every claim you define in these fields. id_token: { # The `required` field defines key-value pairs that must be included with the ID token. # The values must match exactly what is defined. # In this example, the 'acr' (Authentication Context Class Reference) claim # must have the value 'gold' to pass the step-up authentication challenge. # This ensures a specific level of authentication assurance. required: { acr: 'gold' }, # The `included` field also defines key-value pairs that must be included with the ID token. # Multiple accepted values can be defined in an array. If an array is not used, the value must match exactly. # In this example, the 'amr' (Authentication Method References) claim # must have a value of either 'mfa' or 'fpt' to pass the step-up authentication challenge. # This is useful for scenarios where the user must provide additional authentication factors. included: { amr: ['mfa', 'fpt'] }, }, # The `params` field defines any additional parameters that are sent during the authentication process. # In this example, the `claims` parameter is added to the authorization request and instructs the # identity provider to include an 'acr' claim with the value 'gold' in the ID token. # The 'essential: true' indicates that this claim is required for successful authentication. params: { claims: { id_token: { acr: { essential: true, values: ['gold'] } } } } }, } } -
구성 파일을 저장하고 GitLab을 다시 시작하여 변경 사항을 적용합니다.
그룹에 단계적 인증 강제#
사용자가 그룹에 액세스하기 전에 단계적 인증을 완료하도록 강제할 수 있습니다. 이 설정은 그룹별로 개별 관리되지만, 이전에 인스턴스 전체에 추가된 단계적 인증 공급자가 필요합니다.
사전 요구 사항:
- 인스턴스의 그룹용 단계적 인증 공급자.
- Owner 권한이 있어야 합니다.
그룹에 단계적 인증을 강제하려면 다음과 같이 합니다.
- 상단 바에서 Search or go to를 선택하고 그룹을 찾습니다.
- 왼쪽 사이드바에서 Settings > General을 선택합니다.
- Permissions and group features 섹션을 확장합니다.
- Step-up authentication에서 사용 가능한 인증 공급자를 선택합니다.
- Save changes를 선택합니다.
단계적 인증에 사용자 정의 문서 링크 추가#
단계적 인증에 실패하면 GitLab은 조직의 인증 요구 사항을 사용자가 이해하도록 돕는 사용자 정의 문서 링크를 표시할 수 있습니다. 이 기능을 사용하면 관리자가 사용자를 내부 문서나 도움말 리소스로 안내하는 조직별 지침을 제공할 수 있습니다.
사용자 정의 문서 링크를 추가하려면 다음과 같이 합니다.
-
GitLab 구성 파일(
gitlab.yml또는/etc/gitlab/gitlab.rb)을 편집하여step_up_auth => admin_mode에documentation_link필드를 추가합니다.production: &base omniauth: providers: - { name: 'openid_connect', label: 'Corporate SSO', # ... other provider configuration ... step_up_auth: { admin_mode: { # ... id_token and params configuration ... documentation_link: 'https://internal.example.com/path/to/documentation' } } } -
구성 파일을 저장하고 GitLab을 다시 시작하여 변경 사항을 적용합니다.
사용자가 단계적 인증에 실패하면 실패한 공급자와 관련된 문서로 연결되는 링크가 포함된 유용한 오류 메시지가 표시됩니다. 링크는 단계적 인증이 실제로 실패한 공급자에 대해서만 표시되므로 안내가 더 관련성 있고 실행 가능해집니다.
문서 링크 모범 사례:
- 보안을 위해 HTTPS URL을 사용합니다.
- 조직의 구체적인 인증 요구 사항을 설명하는 내부 문서로 연결합니다.
MFA또는 기타 필요한 인증 방법을 활성화하는 방법에 관한 정보를 포함합니다.
세션 만료 비활성화#
기본적으로 단계적 인증 세션은 ID 공급자(IdP) 토큰 만료 시간에 따라 만료되며, 일반적으로 약 10분입니다.
session_expiration_enabled 설정으로 세션 만료를 제어할 수 있습니다.
| 설정 | 동작 |
|---|---|
session_expiration_enabled: true (기본값) |
단계적 인증은 IdP 토큰 exp 클레임에 따라 만료됩니다. 일반적으로 약 10분입니다. |
session_expiration_enabled: false |
단계적 인증은 사용자가 로그아웃할 때까지 전체 사용자 세션 동안 유효합니다. |
세션 만료를 비활성화하면 사용자는 주기적으로 신원을 다시 확인하지 않고 세션당 한 번만 인증합니다. 보안 요구 사항이 세션 수명 동안 유지되는 단계적 인증을 허용하는 경우에만 이 설정을 비활성화합니다.
세션 만료를 비활성화하려면 다음과 같이 합니다.
-
/etc/gitlab/gitlab.rb를 편집합니다.gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", label: "Provider name", args: { name: "openid_connect", # ... other args ... }, step_up_auth: { session_expiration_enabled: false, # Disable session expiration admin_mode: { # ... admin_mode config ... }, namespace: { # ... namespace config ... } } } ] -
파일을 저장하고 GitLab을 재구성합니다.
sudo gitlab-ctl reconfigure
-
config/gitlab.yml을 편집합니다.production: &base omniauth: providers: - { name: 'openid_connect', label: 'Provider name', args: { name: 'openid_connect', # ... other args ... }, step_up_auth: { session_expiration_enabled: false, admin_mode: { # ... admin_mode config ... }, namespace: { # ... namespace config ... } } } -
파일을 저장하고 GitLab을 다시 시작합니다.
# For systems running systemd sudo systemctl restart gitlab.target # For systems running SysV init sudo service gitlab restart
문제 해결#
discovery가true로 설정되어 있는지 확인합니다.false로 설정한 경우 OpenID가 작동하는 데 필요한 모든 URL과 키를 지정해야 합니다.- 시스템 시계를 확인하여 시간이 올바르게 동기화되어 있는지 확인합니다.
- OmniAuth OpenID Connect 문서에서 언급했듯이
issuer가 Discovery URL의 기본 URL과 일치하는지 확인합니다. 예를 들어https://accounts.google.com은 URLhttps://accounts.google.com/.well-known/openid-configuration에 사용됩니다. client_auth_method가 정의되지 않았거나basic으로 설정된 경우 OpenID Connect 클라이언트는 HTTP Basic 인증으로 OAuth 2.0 액세스 토큰을 전송합니다.userinfo엔드포인트를 가져올 때 401 오류가 표시되면 OpenID 웹 서버 구성을 확인합니다. 예를 들어oauth2-server-php에서는 Apache에 구성 매개변수를 추가해야 할 수 있습니다.- 단계적 인증에만 해당:
step_up_auth => admin_mode => params에 정의한 모든 매개변수를args => allow_authorize_params에도 정의했는지 확인합니다. 여기에는 IdP 인가 엔드포인트로 리디렉션하는 데 사용되는 요청 쿼리 매개변수의 매개변수도 포함됩니다.