Skip to content

Azure Active Directory B2C setup

Glossary

  • AD B2C : Azure Active Directory B2C
  • IDP : Identity provider

Description

Azure Active Directory B2C is an Azure resource dedicated to the handling of user accounts and authentication. It exposes Oauth 2.0 and OIDC endpoints. Using AD B2C offers two main advantages when the solution is deployed on an Azure cloud:

  • It is relatively cheap compared to other identity providers (like Okta, Auth0, etc...): the first 50 000 unique users by month are free of charge
  • No dependency to another SAAS platform is required, the solution stays in Azure

Authentication use cases

By nature, OAuth handles several use cases for the management of user accounts. For now, only one of them is supported in the solution, but it can be customized for the customer if necessary.

Internal users only (supported)

In this configuration, internal user accounts are created in the AD B2C tenant. It means that every user will have an account dedicated to the solution, with dedicated credentials. AD B2C will store and validate the passwords, and handle the password reset flow.

Pros:

  • Simple to setup

Cons:

  • Users have to remember another account
  • The customer's IT team probably already have created user accounts for their employees. Those user accounts cannot be reused, so they have to be re-created in the AD B2C tenant in parallel. The user management is duplicated.

Federated identities with public account (unsupported)

In Oauth 2.0, the notion of identity federation basically means that a single login portal can use user accounts provided by different IDPs. It's what is used when you a 'Sign in with LinkedIn', 'Sign in with Microsoft', etc... The authentication portal delegated the validation of the user's credentials to someone else, but is still in charge of providing the authorization through the access tokens (in our case, Json Web Tokens - JWT).

AD B2C can be configured to work this way: it is possible, with a little bit of configuration, to add external IDPs to the login page. Keep in mind that the login & password fields that you'll see on the AD B2C login page are for internal user accounts only. To authenticate with an external IDP, you'll always have to be redirected to its own login page.

Note: It is possible to handle external and internal accounts at the same time.

With this feature, the customer can use its own IDP to the solution, and avoid having to recreate dedicated user accounts, which is much more convenient from an IT service perspective. But the external IDPs are statically declared in AD B2C: the login portal will always show the same ones. The issue here is that if a single instance of Kamea is used by different companies, they'll be able to see each other's IDP, which is not acceptable, especially if those companies are competitors.

In this configuration, it is preferable to only use accounts of public IDPs, like Microsoft, Google, GitHub, LinkedIn, etc... since this does not provide any information about the users of the Kamea.

Pros:

  • No account duplication

Cons:

  • More complex setup
  • Does not apply to all cases

Federated identities with private accounts (unsupported)

This configuration is the same as the previous one, but handles private IDPs, allowing several competitors to use the same product without revealing this information. This flow generally takes a different form: the user is first prompted to input their email address, and is then redirected to the IDP of their company.

Pros:

  • Very flexible, completely avoids the need for account duplication

Cons:

  • Extremely complex to setup, prone to error

Setup

Requirements

Before starting with the AD B2C setup, make sure that your Azure organization allows for this kind of resource to be created. Having a basic understanding of OAuth 2.0 and OIDC is preferable, as this guide will not go into too much details.

Resource creation

Go to your resource group, click the Create button to add a new resource, and search for Azure Active Directory B2C. Select it in the list.

The first step will ask whether to create a new tenant or to link to an existing one. Unless you have specific needs, choose to create a new tenant.

Fill in the form, and click on Review + create, and then on Create if necessary. The creation can take a few minutes.

Once the new tenant is created, note that you'll see it appear as a new tenant available in your Azure tenant list. Be careful:

  • Not to add resource in it
  • Not to add users to the wrong tenant, you might for example add a user on your 'real' tenant while thinking you're modifying the B2C tenant.

In your main tenant, select the AD B2C resource, and in the Overview page, note the Tenant ID value.

Note: You can create a B2C in every resource group for each environment (dev, QA, prod, etc...) or just use a single one. It is up to you, and depends on your needs.

Configuration

In the tenant list, select your new B2C tenant. When it's done, select the resource Azure AD B2C. Search it in the top search bar if necessary. You might want to bookmark this resource, you'll have to come back to it several times.

Several things need to be configured in this tenant: the sign in user flow, and the applications.

User flow

In this step, you'll create the user flow in which users can either:

  • Sign-in only
  • Sign-in and sign-up

This choice must be made based on your use case. The sign-up user flow should only be selected if the final users need to self register to the platform, and if having them input their credentials twice (once during sign-up, and once during the following sign-in) is unacceptable.

Note

See the self check-in documentation for more information.

In the left menu, click on the User flows button, and then on the New user flow button. In the list, select Sign in or Sign up and sign in. Use the recommended version, not the standard / legacy one.

Fill-in the form:

  • Name: you might want to simply name it signin for simplicity and clarity
  • Identity providers: check Email signin under the Local accounts label
  • Multifactor authentication: up to you. For the most simple version, leave Email and off checked.
  • Conditional access: leave the checkbox unchecked
  • Application claims: Email Addresses is mandatory if you're using the sign-up user flow. Without it, the JWT token won't contain the user's email address, and the API will fail to register the user after having completed the sign-up on B2C. The rest is up to you. We advise at least Display name, Given name and Surname.

Finalize the creation.

Once it's created, open it through the User flow menu, select Properties, and in the bottom section check the Self-service password reset checkbox. It will allow the users to reset their password on their own, without having to reach out to an administrator.

If you're using a sign-up user flow, you must also go to the menu Application claims and check the Email addresses checkbox. Otherwise, the JWT won't contain the user's email address. This setting can take quite a long time to take effect (sometimes up to an hour), so you might not have the email address in the token right away.

Applications

Now you need to register 3 applications: the SPA front-end, the API, and one that will be used to access the Graph management API to create / read / update / delete users.

For each of those applications, you'll have to create an App Registration. To do that, in the AD B2C resource, simply go to the App registrations menu, and click on the New registration. The next sections consider that you are on the creation form.

API

  • Name: up to you. If you are not on a production environment, it is advised to append the environment to the name. Example : Kamea API Dev
  • Supported account types: leave the default value
  • Redirect URI: Do not add any redirect URI
  • Permissions: leave the default value

Finalize the creation by clicking on Register.

Once it's created, go back to it through the App registrations menu of the AD B2C tenant.

Go to the menu Expose an API. Click on the button Add a scope. It will ask to create an application ID URI. Leave the proposed name, and click on Save and continue. You'll land on the scope creation form. Name it full, as we want to grant a full access to the API, and fill the other values as you want, it is only for display. Click the Add scope button at the bottom to register the scope.

Front-end

Fill-in the form:

  • Name: up to you. If you are not on a production environment, it is advised to append the environment to the name. Example : Kamea Dev
  • Supported account types: leave the default value
  • Redirect URI: In the dropdown list, select SPA. On a dev environment, you'll probably want to add http://localhost:4200 in the text field, or on a production environment the URL of your deployed front-end. Note that the front-ends shipped by default with Kamea will be redirected to a /token endpoint after login. Consequently, you need to add the complete URL including this endpoint to the redirect URIs. Example: https://your-device-management-app.com/token
  • Permissions: leave the default value

Finalize the creation by clicking on Register.

Once it's created, go back to it through the App registrations menu of the AD B2C tenant. Note the Application (client) ID value.

In the Authentication menu, add all your required Redirect URIs. Verify in the Grant types section that your redirect URIs are eligible for the Authorization Code Flow with PKCE. Look at the rest of the values. The default values will work, but you might want to change them. Do not enable the Implicit grant, since it is a less secure alternative to Authorization Code with PKCE.

In the API permissions menu, click on the button Add a permission. Select the tab My APIs: you should see the API you created just before in the list. Click on it. Select Delegated permissions, and select full in the list below. Click on Add permissions to validate. Once the permission has been added, it should indicate that the admin has not granted consent to it. To solve that, click on the Grant admin consent for "your tenant name" button.

Note: Now, users that retrieve a token from the SPA will be authorized to call the API since the API B2C identifier will be present in the JWT audience claim Without doing that, it wouldn't be the case.

Graph API

Microsoft Graph API is the management API for Azure Active Directory, whether it's B2C or not. It's used to manager user accounts, send mails, etc... The last Application Registration that you're going to create is used to call the Graph API. It is required because calling the Graph API requires having a JWT to authenticate the requests. The SPA application you've previously created is used to retrieve a token in a interactive manner, meaning that it requires being done by a human user who'll input their email and password. In our case, the Graph API calls are not going to be made by a final user, but by the Management API, which need to retrieve a token through a back-channel instead of going through the browser flow. The next application is dedicated to retrieving Graph API tokens in a machine-to-machine context.

Fill-in the Application Registration creation form:

  • Name: up to you. If you are not on a production environment, it is advised to append the environment to the name. Example : Kamea Graph Dev
  • Supported account types: Accounts in this organizational directory only
  • Redirect URI: leave it empty
  • Permissions: uncheck the box

Finalize the creation by clicking on Register.

Once it's created, go back to it through the App registrations menu of the AD B2C tenant. Note the Application (client) ID value.

Go to the Certificates & secrets menu. Select the Client secrets tab and click on New client secret. We want to create a secret that will be used by the Management API to retrieve a token from the application. So name it management-api-secret, and set the expiration date you want. Be careful: once it's expired, you'll have to change it in the environment variables of the Management API. Once created, note the secret right away as you won't be able to display it anymore after that. It's advised to store it in a secret management system, like an Azure Key Vault. Be very careful with it, because leaking it means that anyone in its possession would be able to manage your B2C instance by creating users, having control on the passwords, etc...

We now need to give the proper permissions for the Graph API to this application. Otherwise, the application access would be denied for every single request. Go to the API permissions menu, and click on Add a permission. In the Microsoft APIs tab, click on Microsoft Graph, and then on Application permissions. In the list, search for User.ReadWrite.All, select it, and validate it by clicking on the Add permissions at the bottom. If the admin access is not automatically granted, click on the button Grant admin consent for "your tenant name".

ROPC (optional)

The ROPC flow is used to retrieve a token by sending the user credentials to an endpoint, without any redirection. Be careful with it, it should not be used for anything else than testing purposes, as it is deprecated.

Fill-in the Application Registration creation form:

  • Name: up to you. If you are not on a production environment, it is advised to append the environment to the name. Example : Kamea E2E Testing
  • Supported account types: Accounts in this organizational directory only
  • Redirect URI: In the dropdown list, select SPA. On a dev environment, you'll probably want to add http://localhost:4200 in the text field, or on a production environment the URL of your deployed front-end. This shouldn't be required according to the documentation, but (at this time) leaving the application without any redirect URL prevents it from sending token through ROPC
  • Permissions: uncheck the box

Once it's created, go back to it through the App registrations menu of the AD B2C tenant. Note the Application (client) ID value. In the Authentication menu, enable the checkboxes Access tokens and ID tokens. At the bottom, switch Enable the following mobile and desktop flows to Yes In the Manifest, set oauth2AllowImplicitFlow to true. If this documentation is not exact anymore, check the official one

Your AD B2C tenant is now fully setup and operational.

Environment variables

You have noted some values along the way. You'll have to declare them as environment variables in your CI/CD tool, on your development computer, and as Terraform variables when setting up the rest of the infrastructure.

Here are the required environment variables, and where to find them.

B2C_DOMAIN_NAME: in the AD B2C overview page, look for the Domain name field in the Essentials section at the top

B2C_TENANT_ID: in your main tenant, select your AD B2C resource, and note the Tenant ID in the Overview page

B2C_GRAPH_CLIENT_ID: Open the Graph Application registration (the last you created), and use look for Application (client) ID in the Overview.

B2C_GRAPH_CLIENT_SECRET: The secret you noted while configuring the Application registration for the Graph API.

JWT_AUDIENCE: in the API Application registration, look for the Application (client) ID

JWT_ISSUER: in your sign in user flow, open the Properties menu, and look for the value Issuer (iss) claim. The list might contain 2 elements. Choose the one that has the form: https://<domain>/<id>/v2.0/. Be careful, the <domain> value is not the one you used for the variable B2C_DOMAIN_NAME. It must be <your-b2c-tenant-name>.b2clogin.com.

JWT_ISSUER_WELL_KNOWN_URL: in your B2C tenant, in the App registrations menu, click on the Endpoints button and look for the value Azure AD B2C OpenID Connect metadata document. Be careful, it contains a variable part! Replace \<policyName> by your sign in user flow name, including the prefix b2c... Open this URL in your browser, and look for the jwks_uri property in the json. Use the URL contained in its value as the value of this environment variable.

Front end environment values

In the source code of the front-ends, you'll also have to update some values to make the authentication work. You'll have to note the discovery document URL (cf the environment variable JWT_ISSUER_WELL_KNOWN_URL), and the Client ID of your SPA Application Registration.

Customize login pages (optional)

By default, all AD B2C login pages (including password reset, etc...) have a default design that will probably need to be customized for the customers. Depending on the use cases, customization will be done differently.

The most straightforward way of doing it is to configure the Company Branding in the B2C main menu. That will allow you to customize the icon and background image of B2C pages, but will not give you full control on the structure of the page. Read this documentation for more details.

Another possibility, which requires more work but offers more control, is to provide a customized HTML file in which B2C will inject its input fields, buttons, etc... It supports custom CSS & Javascript. The files must be deployed and accessible publicly on the internet, and the CORS rules must be configured to allow B2C to access them. Read this documentation for more information.

Note that the HTML file has some restrictions. Be careful when reading the documentation. One restriction that is not documented is that any text in the HTML not put within an HTML tag will completely break the template, which will result in a blank page.