anonymous image

Authenticate your users with Azure Active Directory B2C

We are gonna create an actual Azure Active Directory B2C tenant with user flows for registering and sign in scenarios. After that, we create a web application that will be using it to authenticate users.

This is quite a complex topic. Before you begin reading this it’s required that you have a little knowledge about authentication and authorization on the web. For starters, you must know the difference between them. If you have a little knowledge about this then you are also aware of the fact that today’s web standards are all about OAuth2 and OpenID Connect. https://docs.microsoft.com/en-us/azure/active-directory/develop/authentication-vs-authorization

What are the differences between OAuth and OpenID Connect?

OAuth

To start OAuth is a technical authorization protocol and this protocol describes several scenarios, that are called OAuth flows, that are covered using OAuth. They’re also referred to as “Grant types“. You have the following flows a.k.a. grant types:
– Authorization code flow
– Implicit flow with Form Post (don’t confuse it with the normal implicit flow)
– Implicit flow (don’t use!!!!, see my other blog post)
– Resource Owner Password Flow (not recommend)
– Client credential flow
source:
https://auth0.com/docs/authenticate/protocols/oauth

OpenID Connect

This is where the confusion starts for most people. To put it simply, it’s just a set of rules that tells how the OAuth0 protocol is to be extended and used to be more secure in enterprise environments and situations. Nothing more. Just like Microsoft Exchange is just an extension on Active Directory properties.
You can get confused because you see in many documentation the terms that are used by the OAuth protocol. That’s because the OpenID protocol uses the technical flows of OAuth to make sure that more complex enterprise situations can be securely handled.
The ID token plays a crucial role in the OpenID protocol and in the OAuth protocol it does not.

Tokens

ID tokens
As described before, the ID tokens play a central role in the OpenID protocol. You can see an ID token as a receipt from the Identity Provider that the user has been identified. The Identity Provider (also called IdP) is software that verified the user, using the OpenID protocol. This software could be IdentityServer or Azure Active Directory B2C. The result is the ID token.
The most important parts of the ID token are:
sub (subject, mostly the user)
iss (issuer of the token, mostly the IdP)
aud (the audience for who is this token being requested)
acr (how the user is authenticated)
iat (when the user was authenticated)
exp (expiration time of the token)

The receiving party needs to evaluate these parts carefully. Also, the ID token needs to be signed with a private certificate. The receiving party uses the public certificate to validate the signature of the Token.

Access tokens
The access token is an OAuth token which can be granted to a user after login. After the login process, the user gets an Access Token in the form of a JWT token. Also called a bearer token. These bearer tokens need to be sent along with the user requests to other 3rd party software or WebApi’s. Based on the scopes and the claims inside the token access can be granted or not.

Refresh token
As explained before, the access token has an expiration time. But it happens often that the user needs more time with the web application than the access tokens allow. That’s where a refresh token comes into play. To extend the validity of the access token, the refresh token is needed. The refresh token is sent to the IdP. The IdP verifies that this refresh token belongs to the user and extends the session of the user by giving them a new access token.

Azure Active Directory B2C

Azure Active Directory B2C (Business to Consumer) is a separate Azure resource that allows you to manage user identities and access your resources. It’s not to be confused with the Azure Active Directory. It’s not the same. It’s a separate service so you don’t contaminate your Active Directory with external users.
See the picture below.

My Azure Active Directory B2C instance is beside my normal Azure Active Directory

Just like Identity Server, Azure AD B2C gives you the possibility to let users register, sign in, and sign out. It uses OpenID connect and because of this, you are also able to use SSO (Single Sign-On) among all your applications that you have connected with Azure B2C.

To start using Azure B2C, it’s mandatory that you first create an Azure B2C tenant for your use.
Go to the Azure Portal and search for Azure Active Directory B2C and create one. It’s free.

Azure Active Directory B2C user flows

Once the B2C resource has been created you can start with the registrations of your Apps and with the User flows. The User-Flows are the processes that you can define and customize in Azure B2C. These flows are about different user login and/or registration scenarios and the way Azure B2C can facilitate the user. Default Azure B2C has the default flows defined. Which can be used right out of the box

different “out of the box” user flows


But there are different ways you can extend these login and/or registration scenarios with API Connectors and Identity Framework extensions. Add API connectors to sign up user flows | Microsoft Docs
With these, you can customize the flow to get the right information from your users.

Create an Azure Active Directory B2C and register your app

Now let’s first try to hook up a simple server-based web application.

First, create an Azure Active Directory B2C resource in Azure.

Create an Azure Active Directory B2C resource

After it has been created, use the Azure Portal to navigate to your new Azure Active Directory B2C. As mentioned earlier this new Active Directory exists besides your normal Azure Active Directory. This way your Directory will not be contaminated with all user’s profiles.
Now inside your Azure Active Directory B2C resource navigate to App registrations

app registrations

Now create an app registration for your demo app like this

register an application in Azure AD B2C

Please pay attention to your redirect URI. This must end with “signin-oidc”

The last thing we need to configure is the Grant Type. Open your registered application and click in the left menu on “Authentication”. Now make sure that ID tokens are selected.

Attention if this were a SPA application (client-side) both had to be unchecked!

Open your Visual Studio installation and let’s start with a simple MVC application project and create your project using the following settings.

Make sure you select the authentication type “Microsoft Identity Platform

We are gonna use the new Microsoft Identity Platform. This is a wrapper that Microsoft has made around the MSAL libs.
https://docs.microsoft.com/en-us/azure/active-directory/develop/microsoft-identity-web
Now open your program.cs file and make sure you have the following lines

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"));

builder.Services.AddControllersWithViews(options =>
{
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
});
builder.Services.AddRazorPages()
    .AddMicrosoftIdentityUI();

Next, make sure that you have the following appsettings.json

  // Login with Azure B2C
  "AzureAdB2C": {
    "Instance": "https://<name of your tenant>.b2clogin.com",
    "ClientId": "<your client id>",
    "Domain": "<domain name>.onmicrosoft.com",
    "SignedOutCallbackPath": "/signout/<your-sign-up-in-policy>",
    "SignUpSignInPolicyId": "<your-sign-up-in-policy>"
  },

Notice 2 lines in your appsettings.json file.
First is the ClientId, which must correspond with the ClientId, that you have with your app registration inside Azure AD B2C. That will tell Azure B2C what app is going to use your Azure Active Directory B2C authentication.
The second line you need to pay attention to is SignUpSignInPolicyId. This line need to correspond to the SignUpSignIn user flow that you need to have configured (we do this in the next paragraph).

Setup your SignUpSignInPolicy

In the main menu of your Azure Active Directory B2C, you will see the option “User flows“. Click on this to start creating a user flow.

user flow

You can now see the “out of the box” user flows. My advice is to use these as much as possible before you want to create your flow. These flows are well tested and are from Microsoft itself. Now select the recommended “Sign up and sign in” flows.

select Sign up and sign in

This flow offers the users a login screen, but also a registration page if they don’t have an account yet. On the next screen, you can configure some details about the login process. We are gonna keep it simple:
1. choose a name for this user flow
2. select the “Email signup” options
3. select the type of method “Email” and set the Multi-factor authentication to “None”
4. leave the conditional options blank
5. select “given name” and “surname”

Now you have successfully created a user flow in which users can use their email addresses to log in and/or register themselves to your web application.
We still need to update the appsetting.json to let the application and Azure AD B2C use the flow. Remember the SignUpSignInPolicyId. Now copy and paste the complete name of the Policy. That’s it! My complete appsettings.json looks like this now

"AzureAdB2C": {
    "Instance": "https://allardtest.b2clogin.com",
    "ClientId": "<<secret>>",
    "Domain": "allardtest.onmicrosoft.com",
    "SignedOutCallbackPath": "/signout/B2C_1_allardtest_sign_in",
    "SignUpSignInPolicyId": "B2C_1_allardtest_sign_in"

Connecting a Blazor App to Azure Active Directory B2C

When you are going to use a Blazor WASM application you cannot use the same settings as for a server-side web application. Blazor WASM is a SPA application and most of the MSAL code is being done in javascript.

javascript for

because of that, it’s mandatory that we are going to use the OAuth PKCE Code flow. This requires some extra configuration on Azure AD B2C.
You need to register your Blazor WASM application like so (see picture)

Sources

https://connect2id.com/learn/openid-connect#claims
https://auth0.com/docs
https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-sign-user-overview?tabs=aspnetcore
https://docs.microsoft.com/en-us/azure/active-directory/develop/microsoft-identity-web
https://docs.microsoft.com/en-us/azure/active-directory/develop/authentication-vs-authorization