Commit 5889dadb authored by Stan Hu's avatar Stan Hu

Merge branch 'sh-azure-b2c-docs' into 'master'

Add instructions on how to set up Azure B2C with OpenID Connect

See merge request gitlab-org/gitlab!59894
parents 6edf99aa e99cf0bf
...@@ -134,7 +134,7 @@ See the [Google documentation](https://developers.google.com/identity/protocols/ ...@@ -134,7 +134,7 @@ See the [Google documentation](https://developers.google.com/identity/protocols/
for more details: for more details:
```ruby ```ruby
gitlab_rails['omniauth_providers'] = [ gitlab_rails['omniauth_providers'] = [
{ {
'name' => 'openid_connect', 'name' => 'openid_connect',
'label' => 'Google OpenID', 'label' => 'Google OpenID',
...@@ -153,6 +153,7 @@ for more details: ...@@ -153,6 +153,7 @@ for more details:
} }
} }
} }
]
``` ```
### Microsoft Azure ### Microsoft Azure
...@@ -170,7 +171,7 @@ to obtain the tenant ID, client ID, and client secret for your app. ...@@ -170,7 +171,7 @@ to obtain the tenant ID, client ID, and client secret for your app.
Example Omnibus configuration block: Example Omnibus configuration block:
```ruby ```ruby
gitlab_rails['omniauth_providers'] = [ gitlab_rails['omniauth_providers'] = [
{ {
'name' => 'openid_connect', 'name' => 'openid_connect',
'label' => 'Azure OIDC', 'label' => 'Azure OIDC',
...@@ -189,11 +190,159 @@ Example Omnibus configuration block: ...@@ -189,11 +190,159 @@ Example Omnibus configuration block:
} }
} }
} }
]
``` ```
Microsoft has documented how its platform works with [the OIDC protocol](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc). Microsoft has documented how its platform works with [the OIDC protocol](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc).
## Troubleshooting ### Microsoft Azure Active Directory B2C
While GitLab works with [Azure Active Directory B2C](https://docs.microsoft.com/en-us/azure/active-directory-b2c/overview), it requires special
configuration to work. To get started, sign in to the [Azure Portal](https://portal.azure.com).
For your app, you'll need the following information from Azure:
- A tenant ID. You may already have one. For more information, review the
[Microsoft Azure Tenant](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-create-new-tenant) documentation.
- A client ID and a client secret. Follow the instructions in the
[Microsoft tutorial](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga) documentation to obtain the
client ID and client secret for your app.
- The user flow or policy name. Follow the instructions in the [Microsoft tutorial](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-user-flow).
If your GitLab domain is `gitlab.example.com`, ensure the app has the following `Redirect URI`:
`https://gitlab.example.com/users/auth/openid_connect/callback`
In addition, ensure that [ID tokens are enabled](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga#enable-id-token-implicit-grant).
Add the following API permissions to the app:
1. `openid`
1. `offline_access`
#### Configure custom policies
Azure B2C [offers two ways of defining the business logic for logging in a user](https://docs.microsoft.com/en-us/azure/active-directory-b2c/user-flow-overview):
- [User flows](https://docs.microsoft.com/en-us/azure/active-directory-b2c/user-flow-overview#user-flows)
- [Custom policies](https://docs.microsoft.com/en-us/azure/active-directory-b2c/user-flow-overview#custom-policies)
While cumbersome to configure, custom policies are required because
standard Azure B2C user flows [do not send the OpenID `email` claim](https://github.com/MicrosoftDocs/azure-docs/issues/16566). In
other words, they do not work with the [`allow_single_sign_on` or `auto_link_user`
parameters](../../integration/omniauth.md#initial-omniauth-configuration).
With a standard Azure B2C policy, GitLab cannot create a new account or
link to an existing one with an e-mail address.
Carefully follow the instructions for [creating a custom policy](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy).
The Microsoft instructions use `SocialAndLocalAccounts` in the [custom policy starter pack](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy#custom-policy-starter-pack),
but `LocalAccounts` works for authenticating against local, Active Directory accounts. Before you follow the instructions to [upload the polices](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy#upload-the-policies), do the following:
1. To export the `email` claim, modify the `SignUpOrSignin.xml`. Replace the following line:
```xml
<OutputClaim ClaimTypeReferenceId="email" />
```
with:
```xml
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
```
1. For OIDC discovery to work with B2C, the policy must be configured with an issuer compatible with the [OIDC
specification](https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.4.3).
See the [token compatibility settings](https://docs.microsoft.com/en-us/azure/active-directory-b2c/configure-tokens?pivots=b2c-custom-policy#token-compatibility-settings).
In `TrustFrameworkBase.xml` under `JwtIssuer`, set `IssuanceClaimPattern` to `AuthorityWithTfp`:
```xml
<ClaimsProvider>
<DisplayName>Token Issuer</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="JwtIssuer">
<DisplayName>JWT Issuer</DisplayName>
<Protocol Name="None" />
<OutputTokenFormat>JWT</OutputTokenFormat>
<Metadata>
<Item Key="IssuanceClaimPattern">AuthorityWithTfp</Item>
...
```
1. Now [upload the policy](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy#upload-the-policies). Overwrite
the existing files if you are updating an existing policy.
1. Determine the issuer URL using the sign-in policy. The issuer URL will be in the form:
```markdown
https://<YOUR-DOMAIN>/tfp/<YOUR-TENANT-ID>/<YOUR-SIGN-IN-POLICY-NAME>/v2.0/
```
The policy name is lowercased in the URL. For example, `B2C_1A_signup_signin`
policy appears as `b2c_1a_signup_sigin`.
Note that the trailing forward slash is required.
1. Verify the operation of the OIDC discovery URL and issuer URL, append `.well-known/openid-configuration`
to the issuer URL:
```markdown
https://<YOUR-DOMAIN>/tfp/<YOUR-TENANT-ID>/<YOUR-SIGN-IN-POLICY-NAME>/v2.0/.well-known/openid-configuration
```
For example, if `domain` is `example.b2clogin.com` and tenant ID is `fc40c736-476c-4da1-b489-ee48cee84386`, you can use `curl` and `jq` to
extract the issuer:
```shell
$ curl --silent "https://example.b2clogin.com/tfp/fc40c736-476c-4da1-b489-ee48cee84386/b2c_1a_signup_signin/v2.0/.well-known/openid-configuration" | jq .issuer
"https://example.b2clogin.com/tfp/fc40c736-476c-4da1-b489-ee48cee84386/b2c_1a_signup_signin/v2.0/"
```
1. Configure the issuer URL with the custom policy used for
`signup_signin`. For example, this is the Omnibus configuration with a
custom policy for `b2c_1a_signup_signin`:
```ruby
gitlab_rails['omniauth_providers'] = [
{
'name' => 'openid_connect',
'label' => 'Azure B2C OIDC',
'args' => {
'name' => 'openid_connect',
'scope' => ['openid'],
'response_mode' => 'query',
'response_type' => 'id_token',
'issuer' => 'https://<YOUR-DOMAIN>/tfp/<YOUR-TENANT-ID>/b2c_1a_signup_signin/v2.0/',
'client_auth_method' => 'query',
'discovery' => true,
'send_scope_to_token_endpoint' => true,
'client_options' => {
'identifier' => '<YOUR APP CLIENT ID>',
'secret' => '<YOUR APP CLIENT SECRET>',
'redirect_uri' => 'https://gitlab.example.com/users/auth/openid_connect/callback'
}
}
}]
```
#### Troubleshooting Azure B2C
- Ensure all occurrences of `yourtenant.onmicrosoft.com`, `ProxyIdentityExperienceFrameworkAppId`, and `IdentityExperienceFrameworkAppId` match your B2C tenant hostname and
the respective client IDs in the XML policy files.
- Add `https://jwt.ms` as a redirect URI to the app, and use the [custom policy tester](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy#test-the-custom-policy).
Make sure the payload includes `email` that matches the user's e-mail access.
- After you enable the custom policy, users might see "Invalid username or password" after they try to sign in. This might be a configuration
issue with the `IdentityExperienceFramework` app. See [this Microsoft comment](https://docs.microsoft.com/en-us/answers/questions/50355/unable-to-sign-on-using-custom-policy.html?childToView=122370#comment-122370)
that suggests checking that the app manifest contains these settings:
- `"accessTokenAcceptedVersion": null`
- `"signInAudience": "AzureADMyOrg"`
1. `"signInAudience": "AzureADMyOrg"`
Note that this configuration corresponds with the `Supported account types` setting used when creating the `IdentityExperienceFramework` app.
## General troubleshooting
If you're having trouble, here are some tips: If you're having trouble, here are some tips:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment