Use Microsoft Azure as an OAuth 2.0 authentication provider

You can enable the Microsoft Azure OAuth 2.0 OmniAuth provider and sign in to GitLab with your Microsoft Azure credentials. You can configure the provider that uses the earlier Azure Active Directory v1.0 endpoint, or the provider that uses the v2.0 endpoint.

note
For new projects, Microsoft suggests you use the OpenID Connect protocol, which uses the Microsoft identity platform (v2.0) endpoint.

Migrate to the OpenID Connect protocol

To migrate to the OpenID Connect protocol, see configure multiple OpenID Connect providers.

You must set the uid_field, which differs across the providers:

ProvideruidRemarks
omniauth-azure-oauth2subAdditional attributes oid, tid are offered within the info object
omniauth-azure-activedirectory-v2oidYou must configure oid as uid_field when migrating
omniauth_openid_connectsubSpecify uid_field to use another field

To migrate from omniauth-azure-oauth2 to omniauth_openid_connect you must change the configuration.

Linux package (Omnibus)

Remove some of the existing configuration and add new configuration as shown.

gitlab_rails['omniauth_providers'] = [
  {
    name: "azure_oauth2",
    # label: "Provider name", # optional label for login button, defaults to "Azure AD"
    args: {
+      name: "azure_oauth2",
+      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
+      scope: ["openid", "profile", "email"],
+      response_type: "code",
+      issuer:  "https://login.microsoftonline.com/<tenant_id>/v2.0",
+      client_auth_method: "query",
+      discovery: true,
+      uid_field: "sub",
+      client_options: {
+        identifier: "<client_id>",
+        secret: "<client_secret>",
+        redirect_uri: "https://gitlab.example.com/users/auth/azure_oauth2/callback"
+      }
-      client_id: "<client_id>",
-      client_secret: "<client_secret>",
-      tenant_id: "<tenant_id>",
    }
  }
]
Self-compiled (source)

Remove some of the existing configuration and add new configuration as shown.

  - { name: 'azure_oauth2',
      # label: 'Provider name', # optional label for login button, defaults to "Azure AD"
-      args: { client_id: '<client_id>',
-              client_secret: '<client_secret>',
-              tenant_id: '<tenant_id>' } }
+      icon: "<custom_provider_icon>",
+      args: {
+        name: "azure_oauth2",
+        strategy_class: "OmniAuth::Strategies::OpenIDConnect",
+        scope: ["openid","profile","email"],
+        response_type: "code",
+        issuer: 'https://login.microsoftonline.com/<tenant_id>/v2.0',
+        discovery: true,
+        client_auth_method: 'query',
+        uid_field: 'sub',
+        send_scope_to_token_endpoint: "false",
+        client_options: {
+          identifier: "<client_id>",
+          secret: "<client_secret>",
+          redirect_uri: "<your_gitlab_url>/users/auth/azure_oauth2/callback"
+        }
+      }
    }

To migrate for example from omniauth-azure-activedirectory-v2 to omniauth_openid_connect you must change the configuration.

Linux package (Omnibus)

Remove some of the existing configuration and add new configuration as shown.

gitlab_rails['omniauth_providers'] = [
  {
 -    name: "azure_activedirectory_v2",
    # label: "Provider name", # optional label for login button, defaults to "Azure AD v2"
    args: {
+      name: "azure_activedirectory_v2",
+      strategy_class: "OmniAuth::Strategies::OpenIDConnect",
+      scope: ["openid", "profile", "email"],
+      response_type: "code",
+      issuer:  "https://login.microsoftonline.com/<tenant_id>/v2.0",
+      client_auth_method: "query",
+      discovery: true,
+      uid_field: "oid",
+      client_options: {
+        identifier: "<client_id>",
+        secret: "<client_secret>",
+        redirect_uri: "https://gitlab.example.com/users/auth/azure_activedirectory_v2/callback"
+      }
-      client_id: "<client_id>",
-      client_secret: "<client_secret>",
-      tenant_id: "<tenant_id>",
    }
  }
]
Self-compiled (source)

Remove some of the existing configuration and add new configuration as shown.

  - { name: 'azure_activedirectory_v2',
      # label: 'Provider name', # optional label for login button, defaults to "Azure AD v2"
-      args: { client_id: '<client_id>',
-              client_secret: '<client_secret>',
-              tenant_id: '<tenant_id>' } }
+      icon: "<custom_provider_icon>",
+      args: {
+        name: "azure_activedirectory_v2",
+        strategy_class: "OmniAuth::Strategies::OpenIDConnect",
+        scope: ["openid","profile","email"],
+        response_type: "code",
+        issuer: 'https://login.microsoftonline.com/<tenant_id>/v2.0',
+        discovery: true,
+        client_auth_method: 'query',
+        uid_field: 'oid',
+        send_scope_to_token_endpoint: "false",
+        client_options: {
+          identifier: "<client_id>",
+          secret: "<client_secret>",
+          redirect_uri: "<your_gitlab_url>/users/auth/azure_activedirectory_v2/callback"
+        }
+      }
    }

For more information on other customizations, see gitlab_username_claim.

Register an Azure application

To enable the Microsoft Azure OAuth 2.0 OmniAuth provider, you must register an Azure application and get a client ID and secret key.

  1. Sign in to the Azure portal.
  2. If you have multiple Azure Active Directory tenants, switch to the desired tenant. Note the tenant ID.
  3. Register an application and provide the following information:
    • The redirect URI, which requires the URL of the Azure OAuth callback of your GitLab installation. For example:
      • For the v1.0 endpoint: https://gitlab.example.com/users/auth/azure_oauth2/callback.
      • For the v2.0 endpoint: https://gitlab.example.com/users/auth/azure_activedirectory_v2/callback.
    • The application type, which must be set to Web.
  4. Save the client ID and client secret. The client secret is only displayed once.

    If required, you can create a new application secret.

client ID and client secret are terms associated with OAuth 2.0. In some Microsoft documentation, the terms are named Application ID and Application Secret.

Add API permissions (scopes)

If you’re using the v2.0 endpoint, after you create the application, configure it to expose a web API. Add the following delegated permissions under the Microsoft Graph API:

  • email
  • openid
  • profile

Alternatively, add the User.Read.All application permission.

Enable Microsoft OAuth in GitLab

  1. On your GitLab server, open the configuration file.

    • For Linux package installations:

      sudo editor /etc/gitlab/gitlab.rb
      
    • For self-compiled installations:

      cd /home/git/gitlab
      
      sudo -u git -H editor config/gitlab.yml
      
  2. Configure the common settings to add azure_oauth2 as a single sign-on provider. This enables Just-In-Time account provisioning for users who do not have an existing GitLab account.

  3. Add the provider configuration. Replace <client_id>, <client_secret>, and <tenant_id> with the values you got when you registered the Azure application.

    • For Linux package installations:

      For the v1.0 endpoint:

      gitlab_rails['omniauth_providers'] = [
        {
          name: "azure_oauth2",
          # label: "Provider name", # optional label for login button, defaults to "Azure AD"
          args: {
            client_id: "<client_id>",
            client_secret: "<client_secret>",
            tenant_id: "<tenant_id>",
          }
        }
      ]
      

      For the v2.0 endpoint:

      gitlab_rails['omniauth_providers'] = [
        {
          "name" => "azure_activedirectory_v2",
          "label" => "Provider name", # optional label for login button, defaults to "Azure AD v2"
          "args" => {
            "client_id" => "<client_id>",
            "client_secret" => "<client_secret>",
            "tenant_id" => "<tenant_id>",
          }
        }
      ]
      

      For alternative Azure clouds, configure base_azure_url under the args section. For example, for Azure Government Community Cloud (GCC):

      gitlab_rails['omniauth_providers'] = [
        {
          "name" => "azure_activedirectory_v2",
          "label" => "Provider name", # optional label for login button, defaults to "Azure AD v2"
          "args" => {
            "client_id" => "<client_id>",
            "client_secret" => "<client_secret>",
            "tenant_id" => "<tenant_id>",
            "base_azure_url" => "https://login.microsoftonline.us"
          }
        }
      ]
      
    • For self-compiled installations:

      For the v1.0 endpoint:

      - { name: 'azure_oauth2',
          # label: 'Provider name', # optional label for login button, defaults to "Azure AD"
          args: { client_id: '<client_id>',
                  client_secret: '<client_secret>',
                  tenant_id: '<tenant_id>' } }
      

      For the v2.0 endpoint:

      - { name: 'azure_activedirectory_v2',
          label: 'Provider name', # optional label for login button, defaults to "Azure AD v2"
          args: { client_id: "<client_id>",
                  client_secret: "<client_secret>",
                  tenant_id: "<tenant_id>" } }
      

      For alternative Azure clouds, configure base_azure_url under the args section. For example, for Azure Government Community Cloud (GCC):

      - { name: 'azure_activedirectory_v2',
          label: 'Provider name', # optional label for login button, defaults to "Azure AD v2"
          args: { client_id: "<client_id>",
                  client_secret: "<client_secret>",
                  tenant_id: "<tenant_id>",
                  base_azure_url: "https://login.microsoftonline.us" } }
      

    You can also optionally add the scope for OAuth 2.0 scopes parameter to the args section. The default is openid profile email.

  4. Save the configuration file.

  5. Reconfigure GitLab if you installed using the Linux package, or restart GitLab if you self-compiled your installation.

  6. Refresh the GitLab sign-in page. A Microsoft icon should display below the sign-in form.

  7. Select the icon. Sign in to Microsoft and authorize the GitLab application.

Read Enable OmniAuth for an existing user for information on how existing GitLab users can connect to their new Azure AD accounts.

Troubleshooting

User sign in banner message: Extern UID has already been taken

When signing in, you might get an error that states Extern UID has already been taken.

To resolve this, use the Rails console to check if there is an existing user tied to the account:

  1. Find the extern_uid:

    id = Identity.where(extern_uid: '<extern_uid>')
    
  2. Print the content to find the username attached to that extern_uid:

    pp id
    

If the extern_uid is attached to an account, you can use the username to sign in.

If the extern_uid is not attached to any username, this might be because of a deletion error resulting in a ghost record.

Run the following command to delete the identity to release the extern uid:

 Identity.find('<id>').delete