This article shows how to use multiple Azure B2C user flows from a single ASP.NET Core application. Microsoft.Identity.Web is used to implement the authentication in the client. This is not so easy to implement with multiple schemes as the user flow policy is used in most client URLs and the Microsoft.Identity.Web package overrides an lot of the default settings. I solved this by implementing an account controller to handle the Azure B2C signup user flow initial request and set the Azure B2C policy. It can be useful to split the user flows in the client application, if the user of the application needs to be guided better.
Code https://github.com/damienbod/azureb2c-fed-azuread
The Azure B2C user flows can be implemented as simple user flows. I used a signup flow and a signin, signup flow.

The AddMicrosoftIdentityWebAppAuthentication is used to implement a standard Azure B2C client. There is no need to implement a second scheme and override the default settings of the Microsoft.Identity.Web client because we use a controller to select the flow.
string[]? initialScopes = Configuration.GetValue<string>(
"UserApiOne:ScopeForAccessToken")?.Split(' ');
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C")
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddInMemoryTokenCaches();
services.Configure<MicrosoftIdentityOptions>(
OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Events.OnTokenValidated = async context =>
{
if (ApplicationServices != null && context.Principal != null)
{
using var scope = ApplicationServices.CreateScope();
context.Principal = await scope.ServiceProvider
.GetRequiredService<MsGraphClaimsTransformation>()
.TransformAsync(context.Principal);
}
};
});
The AzureAdB2C app settings configures the sign in, sign up flow. The SignUpSignInPolicyId setting is used to configure the default user flow policy.
"AzureAdB2C": {
"Instance": "https://b2cdamienbod.b2clogin.com",
"ClientId": "8cbb1bd3-c190-42d7-b44e-42b20499a8a1",
"Domain": "b2cdamienbod.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_signup_signin",
"TenantId": "f611d805-cf72-446f-9a7f-68f2746e4724",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath ": "/signout-callback-oidc",
// "ClientSecret": "--use-secrets--"
},
The AccountSignUpController is used to set the policy of the flow we would like to use. The SignUpPolicy method just challenges the Azure B2C OpenID Connect server with the correct policy.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Microsoft.Identity.Web.UI.Areas.MicrosoftIdentity.Controllers;
[AllowAnonymous]
[Route("MicrosoftIdentity/[controller]/[action]")]
public class AccountSignUpController : Controller
{
[HttpGet("{scheme?}")]
public IActionResult SignUpPolicy(
[FromRoute] string scheme,
[FromQuery] string redirectUri)
{
scheme ??= OpenIdConnectDefaults.AuthenticationScheme;
string redirect;
if (!string.IsNullOrEmpty(redirectUri) && Url.IsLocalUrl(redirectUri))
{
redirect = redirectUri;
}
else
{
redirect = Url.Content("~/")!;
}
scheme ??= OpenIdConnectDefaults.AuthenticationScheme;
var properties = new AuthenticationProperties
{ RedirectUri = redirect };
properties.Items[Constants.Policy] = "B2C_1_signup";
return Challenge(properties, scheme);
}
}
The Razor page opens a link to the new controller and challenges the OIDC server with the correct policy.
<li class="nav-item">
<a class="nav-link text-dark"
href="/MicrosoftIdentity/AccountSignUp/SignUpPolicy">Sign Up</a>
</li>
With this approach, an ASP.NET Core application can be extended with multiple user flows and the UI can be improved for the end user as required.
Links
https://docs.microsoft.com/en-us/azure/active-directory-b2c/overview
https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-azure-ad-single-tenant
https://github.com/AzureAD/microsoft-identity-web
https://docs.microsoft.com/en-us/azure/active-directory/develop/microsoft-identity-web
https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-local
https://docs.microsoft.com/en-us/azure/active-directory/
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/azure-ad-b2c
https://github.com/azure-ad-b2c/azureadb2ccommunity.io
https://github.com/azure-ad-b2c/samples
https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/graph-api
[…] Using multiple Azure B2C user flows from ASP.NET Core (Damien Bowden) […]
How would you implement this in a Blazor Server application?
[…] Using multiple Azure B2C user flows from ASP.NET Core – Damien Bowden […]
[…] https://damienbod.com/2022/05/16/using-multiple-azure-b2c-user-flows-from-asp-net-core/ […]