Set up sign-in for multi-tenant Azure Active Directory using custom policies in Azure Active Directory B2C

Note

In Azure Active Directory B2C, custom policies are designed primarily to address complex scenarios. For most scenarios, we recommend that you use built-in user flows.

This article shows you how to enable sign-in for users using the multi-tenant endpoint for Azure Active Directory (Azure AD) by using custom policies in Azure AD B2C. This allows users from multiple Azure AD tenants to sign in using Azure AD B2C, without you having to configure an identity provider for each tenant. However, guest members in any of these tenants will not be able to sign in. For that, you need to individually configure each tenant.

Prerequisites

Complete the steps in Get started with custom policies in Azure Active Directory B2C.

Register an application

To enable sign-in for users from a specific Azure AD organization, you need to register an application within the organizational Azure AD tenant.

  1. Sign in to the Azure portal.

  2. Make sure you're using the directory that contains your organizational Azure AD tenant (for example, contoso.com). Select the Directory + subscription filter in the top menu, and then choose the directory that contains your tenant.

  3. Choose All services in the top-left corner of the Azure portal, and then search for and select App registrations.

  4. Select New registration.

  5. Enter a Name for your application. For example, Azure AD B2C App.

  6. Select Accounts in any organizational directory for this application.

  7. For the Redirect URI, accept the value of Web, and enter the following URL in all lowercase letters, where your-B2C-tenant-name is replaced with the name of your Azure AD B2C tenant.

    https://your-B2C-tenant-name.b2clogin.com/your-B2C-tenant-name.onmicrosoft.com/oauth2/authresp
    

    For example, https://contoso.b2clogin.com/contoso.onmicrosoft.com/oauth2/authresp.

  8. Select Register. Record the Application (client) ID for use in a later step.

  9. Select Certificates & secrets, and then select New client secret.

  10. Enter a Description for the secret, select an expiration, and then select Add. Record the Value of the secret for use in a later step.

Create a policy key

You need to store the application key that you created in your Azure AD B2C tenant.

  1. Make sure you're using the directory that contains your Azure AD B2C tenant. Select the Directory + subscription filter in the top menu, and then choose the directory that contains your Azure AD B2C tenant.
  2. Choose All services in the top-left corner of the Azure portal, and then search for and select Azure AD B2C.
  3. Under Policies, select Identity Experience Framework.
  4. Select Policy keys and then select Add.
  5. For Options, choose Manual.
  6. Enter a Name for the policy key. For example, AADAppSecret. The prefix B2C_1A_ is added automatically to the name of your key when it's created, so its reference in the XML in following section is to B2C_1A_AADAppSecret.
  7. In Secret, enter your client secret that you recorded earlier.
  8. For Key usage, select Signature.
  9. Select Create.

Add a claims provider

If you want users to sign in by using Azure AD, you need to define Azure AD as a claims provider that Azure AD B2C can communicate with through an endpoint. The endpoint provides a set of claims that are used by Azure AD B2C to verify that a specific user has authenticated.

You can define Azure AD as a claims provider by adding Azure AD to the ClaimsProvider element in the extension file of your policy.

  1. Open the TrustFrameworkExtensions.xml file.

  2. Find the ClaimsProviders element. If it does not exist, add it under the root element.

  3. Add a new ClaimsProvider as follows:

    <ClaimsProvider>
      <Domain>commonaad</Domain>
      <DisplayName>Common AAD</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Common-AAD">
          <DisplayName>Multi-Tenant AAD</DisplayName>
          <Description>Login with your Contoso account</Description>
          <Protocol Name="OpenIdConnect"/>
          <Metadata>
            <Item Key="METADATA">https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration</Item>
            <!-- Update the Client ID below to the Application ID -->
            <Item Key="client_id">00000000-0000-0000-0000-000000000000</Item>
            <Item Key="response_types">code</Item>
            <Item Key="scope">openid profile</Item>
            <Item Key="response_mode">form_post</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="UsePolicyInRedirectUri">false</Item>
            <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
            <!-- The key below allows you to specify each of the Azure AD tenants that can be used to sign in. Update the GUIDs below for each tenant. -->
            <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000,https://login.microsoftonline.com/11111111-1111-1111-1111-111111111111</Item>
            <!-- The commented key below specifies that users from any tenant can sign-in. Uncomment if you would like anyone with an Azure AD account to be able to sign in. -->
            <!-- <Item Key="ValidTokenIssuerPrefixes">https://login.microsoftonline.com/</Item> -->
          </Metadata>
          <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="B2C_1A_AADAppSecret"/>
          </CryptographicKeys>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/>
            <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/>
            <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
            <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
            <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
            <OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/>
            <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/>
            <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId"/>
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId"/>
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin"/>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
  4. Under the ClaimsProvider element, update the value for Domain to a unique value that can be used to distinguish it from other identity providers.

  5. Under the TechnicalProfile element, update the value for DisplayName, for example, Contoso Employee. This value is displayed on the sign-in button on your sign-in page.

  6. Set client_id to the application ID of the Azure AD multi-tenant application that you registered earlier.

  7. Under CryptographicKeys, update the value of StorageReferenceId to the name of the policy key that created earlier. For example, B2C_1A_AADAppSecret.

Restrict access

Note

Using https://login.microsoftonline.com/ as the value for ValidTokenIssuerPrefixes allows all Azure AD users to sign in to your application.

You need to update the list of valid token issuers and restrict access to a specific list of Azure AD tenant users who can sign in.

To obtain the values, look at the OpenID Connect discovery metadata for each of the Azure AD tenants that you would like to have users sign in from. The format of the metadata URL is similar to https://login.microsoftonline.com/your-tenant/v2.0/.well-known/openid-configuration, where your-tenant is your Azure AD tenant name. For example:

https://login.microsoftonline.com/fabrikam.onmicrosoft.com/v2.0/.well-known/openid-configuration

Perform these steps for each Azure AD tenant that should be used to sign in:

  1. Open your browser and go to the OpenID Connect metadata URL for the tenant. Find the issuer object and record its value. It should look similar to https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/.
  2. Copy and paste the value into the ValidTokenIssuerPrefixes key. Separate multiple issuers with a comma. An example with two issuers appears in the previous ClaimsProvider XML sample.

Upload the extension file for verification

By now, you have configured your policy so that Azure AD B2C knows how to communicate with your Azure AD directories. Try uploading the extension file of your policy just to confirm that it doesn't have any issues so far.

  1. On the Custom Policies page in your Azure AD B2C tenant, select Upload Policy.
  2. Enable Overwrite the policy if it exists, and then browse to and select the TrustFrameworkExtensions.xml file.
  3. Select Upload.

Register the claims provider

At this point, the identity provider has been set up, but it’s not available in any of the sign-up/sign-in screens. To make it available, you create a duplicate of an existing template user journey, and then modify it so that it also has the Azure AD identity provider.

  1. Open the TrustFrameworkBase.xml file from the starter pack.
  2. Find and copy the entire contents of the UserJourney element that includes Id="SignUpOrSignIn".
  3. Open the TrustFrameworkExtensions.xml and find the UserJourneys element. If the element doesn't exist, add one.
  4. Paste the entire content of the UserJourney element that you copied as a child of the UserJourneys element.
  5. Rename the ID of the user journey. For example, SignUpSignInContoso.

Display the button

The ClaimsProviderSelection element is analogous to an identity provider button on a sign-up/sign-in screen. If you add a ClaimsProviderSelection element for Azure AD, a new button shows up when a user lands on the page.

  1. Find the OrchestrationStep element that includes Order="1" in the user journey that you created in TrustFrameworkExtensions.xml.

  2. Under ClaimsProviderSelects, add the following element. Set the value of TargetClaimsExchangeId to an appropriate value, for example AzureADExchange:

    <ClaimsProviderSelection TargetClaimsExchangeId="AzureADExchange" />
    

Now that you have a button in place, you need to link it to an action. The action, in this case, is for Azure AD B2C to communicate with Azure AD to receive a token. Link the button to an action by linking the technical profile for your Azure AD claims provider.

  1. Find the OrchestrationStep that includes Order="2" in the user journey.

  2. Add the following ClaimsExchange element making sure that you use the same value for Id that you used for TargetClaimsExchangeId:

    <ClaimsExchange Id="AzureADExchange" TechnicalProfileReferenceId="Common-AAD" />
    

    Update the value of TechnicalProfileReferenceId to the Id of the technical profile you created earlier. For example, Common-AAD.

  3. Save the TrustFrameworkExtensions.xml file and upload it again for verification.

Create an Azure AD B2C application

Communication with Azure AD B2C occurs through an application that you register in your B2C tenant. This section lists optional steps you can complete to create a test application if you haven't already done so.

To register an application in your Azure AD B2C tenant, you can use the current Applications experience, or our new unified App registrations (Preview) experience. Learn more about the new experience.

  1. Sign in to the Azure portal.
  2. Select the Directory + subscription filter in the top menu, and then select the directory that contains your Azure AD B2C tenant.
  3. In the left menu, select Azure AD B2C. Or, select All services and search for and select Azure AD B2C.
  4. Select Applications, and then select Add.
  5. Enter a name for the application. For example, testapp1.
  6. For Web App / Web API, select Yes.
  7. For Reply URL, enter https://jwt.ms
  8. Select Create.

Update and test the relying party file

Update the relying party (RP) file that initiates the user journey that you created:

  1. Make a copy of SignUpOrSignIn.xml in your working directory, and rename it. For example, rename it to SignUpSignContoso.xml.
  2. Open the new file and update the value of the PolicyId attribute for TrustFrameworkPolicy with a unique value. For example, SignUpSignInContoso.
  3. Update the value of PublicPolicyUri with the URI for the policy. For example, http://contoso.com/B2C_1A_signup_signin_contoso.
  4. Update the value of the ReferenceId attribute in DefaultUserJourney to match the ID of the user journey that you created earlier. For example, SignUpSignInContoso.
  5. Save your changes and upload the file.
  6. Under Custom policies, select the new policy in the list.
  7. In the Select application drop-down, select the Azure AD B2C application that you created earlier. For example, testapp1.
  8. Copy the Run now endpoint and open it in a private browser window, for example, Incognito Mode in Google Chrome or an InPrivate window in Microsoft Edge. Opening in a private browser window allows you to test the full user journey by not using any currently cached Azure AD credentials.
  9. Select the Azure AD sign in button, for example, Contoso Employee, and then enter the credentials for a user in one of your Azure AD organizational tenants. You're asked to authorize the application, and then enter information for your profile.

If the sign in process is successful, your browser is redirected to https://jwt.ms, which displays the contents of the token returned by Azure AD B2C.

To test the multi-tenant sign-in capability, perform the last two steps using the credentials for a user that exists another Azure AD tenant.

Next steps

When working with custom policies, you might sometimes need additional information when troubleshooting a policy during its development.

To help diagnose issues, you can temporarily put the policy into "developer mode" and collect logs with Azure Application Insights. Find out how in Azure Active Directory B2C: Collecting Logs.