%3CLINGO-SUB%20id%3D%22lingo-sub-1983575%22%20slang%3D%22en-US%22%3EMigrating%20Azure%20AD%20B2C%20integration%20going%20from%20.NET%20Core%203.1%20to%20.NET%205%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1983575%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20year's%20release%20of%20.NET%20happened%20a%20few%20weeks%20ago%20with%20.NET%205.%20(Core%20is%20gone%20from%20the%20name%20now.)%20I%20have%20some%20sample%20code%20that%20works%20as%20sort%20of%20a%20boilerplate%20to%20verify%20basic%20functionality%20without%20containing%20anything%20fancy.%20One%20of%20those%20is%20a%20web%20app%20where%20one%20can%20sign%20in%20through%20Azure%20AD%20B2C.%20Logically%20I%20went%20ahead%20and%20updated%20from%20.NET%20Core%203.1%20to%20.NET%205%20to%20see%20if%20everything%20still%20works.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIt%20works%2C%20but%20there%20are%20recommendations%20that%20you%20should%20put%20in%20some%20extra%20effort%20as%20the%20current%20NuGet%20packages%20are%20on%20their%20way%20to%20deprecation.%20Not%20like%20%22will%20stop%20working%20in%20two%20weeks%22%2C%20but%20might%20as%20well%20tackle%20it%20now.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20Microsoft%20Identity%20platform%20has%20received%20an%20overhaul%20in%20parallel%20to%20.NET%20and%20a%20little%20while%20before%20the%20.NET%205%20release%20the%20Identity%20team%20released%20%3CEM%3EMicrosoft.Identity.Web%3C%2FEM%3E%20packages%20for%20handling%20auth%20in%20web%20apps.%20(Not%20just%20for%20Azure%20AD%20B2C%2C%20but%20identity%20in%20general.)%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EWhy%20is%20this%20upgrade%20necessary%3F%20Well%2C%20the%20old%20libraries%20were%20based%20on%20the%20Azure%20AD%20v1%20endpoints%2C%20but%20these%20new%20libraries%20fully%20support%20the%20v2%20endpoints.%20Which%20is%20great%20when%20going%20for%20full%20compliance%20with%20the%20OAuth%20and%20OpenID%20Connect%20protocols.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EUsing%20my%20sample%20at%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fahelland%2FIdentity-CodeSamples-v2%2Ftree%2Fmaster%2Faad-b2c-custom_policies-dotnet-core%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2Fahelland%2FIdentity-CodeSamples-v2%2Ftree%2Fmaster%2Faad-b2c-custom_policies-dotnet-core%3C%2FA%3E%26nbsp%3B%20I%20wanted%20to%20do%20a%20test%20run%20from%20old%20to%20new.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20current%20code%20is%20using%26nbsp%3B%3CEM%3EMicrosoft.AspNetCore.Authentication.AzureADB2C.UI%3C%2FEM%3E.%20(You%20can%20take%20a%20look%20at%20the%20code%20for%20the%20%3CA%20title%3D%22Upgraded%20to%20.NET%205%22%20href%3D%22https%3A%2F%2Fgithub.com%2Fahelland%2FIdentity-CodeSamples-v2%2Ftree%2Fb6d8def3dcf8c46e38a9419a9dc88d5eb327501b%2Faad-b2c-custom_policies-dotnet-core%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EUpgraded%20to%20.NET%205%3C%2FA%3E%26nbsp%3Bcheckpoint%20for%20reference.)%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EYou%20can%20start%20by%20using%20NuGet%20to%20download%20the%20latest%20version%20of%20%3CEM%3EMicrosoft.Identity.Web%3C%2FEM%3E%20and%20%3CEM%3EMicrosoft.Identity.Web.UI%3C%2FEM%3E.%20(1.4.0%20when%20I'm%20typing%20this.)%20You%20can%20also%20remove%26nbsp%3B%3CSPAN%3E%3CEM%3EMicrosoft.AspNetCore.Authentication.AzureADB2C.UI%3C%2FEM%3E%20while%20you're%20at%20it.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIn%20%3CEM%3EStartup.cs%3C%2FEM%3E%26nbsp%3Byou%20should%20make%20the%20following%20changes%3A%3C%2FP%3E%3CP%3EReplace%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3Eservices.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)%0A%20%20.AddAzureADB2C(options%20%3D%26gt%3B%20Configuration.Bind(%22AzureADB2C%22%2C%20options)).AddCookie()%3B%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EWith%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3Eservices.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)%0A%20%20.AddMicrosoftIdentityWebApp(Configuration.GetSection(%22AzureADB2C%22))%3B%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAnd%20change%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3Eservices.AddRazorPages()%3B%20%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ETo%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3Eservices.AddRazorPages().AddMicrosoftIdentityUI()%3B%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSPAN%3EIf%20you%20have%20been%20doing%20%22classic%22%3C%2FSPAN%3E%3CSPAN%3E%20Azure%20AD%20apps%20you%20will%20notice%20how%20B2E%20and%20B2C%20are%20now%20almost%20identical.%20Seeing%20how%20they%20both%20follow%20the%20same%20set%20of%20standards%20this%20makes%20sense.%20As%20well%20as%20making%20it%20easier%20for%20.NET%20devs%20to%20support%20both%20internal%20and%20external%20facing%20authentication.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EB2C%20has%20some%20extra%20logic%20in%20the%20sense%20that%20the%20different%20policies%20drive%20you%20to%20different%20endpoints%2C%20so%20the%20UI%20has%20to%20have%20awareness%20of%20this.%20And%20you%20need%20to%20modify%20a%20few%20things%20in%20the%20views.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIn%20%3CEM%3ELoginPartial.cshtml%3C%2FEM%3E%3A%3C%2FP%3E%3CP%3EChange%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3E%40using%20Microsoft.AspNetCore.Authentication.AzureADB2C.UI%0A%40using%20Microsoft.Extensions.Options%0A%40inject%20IOptionsMonitor%3CAZUREADB2COPTIONS%3E%20AzureADB2COptions%0A%0A%40%7B%0A%20%20var%20options%20%3D%20AzureADB2COptions.Get(AzureADB2CDefaults.AuthenticationScheme)%3B%20%20%20%0A%7D%3C%2FAZUREADB2COPTIONS%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ETo%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3E%40using%20Microsoft.Extensions.Options%0A%40using%20Microsoft.Identity.Web%0A%40inject%20IOptions%3CMICROSOFTIDENTITYOPTIONS%3E%20AzureADB2COptions%0A%0A%40%7B%0A%20%20var%20options%20%3D%20AzureADB2COptions.Value%3B%0A%7D%3C%2FMICROSOFTIDENTITYOPTIONS%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAnd%20change%20the%20asp-area%20in%20links%20from%20using%20AzureADB2C%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3E%3CA%20class%3D%22nav-link%20text-dark%22%20asp-area%3D%22AzureADB2C%22%20asp-controller%3D%22Account%22%20asp-action%3D%22SignOut%22%20target%3D%22_blank%22%3ESign%20out%3C%2FA%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ETo%20using%20MicrosoftIdentity%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-csharp%22%3E%3CCODE%3E%3CA%20class%3D%22nav-link%20text-dark%22%20asp-area%3D%22MicrosoftIdentity%22%20asp-controller%3D%22Account%22%20asp-action%3D%22SignOut%22%20target%3D%22_blank%22%3ESign%20out%3C%2FA%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAnd%20that's%20all%20there%20is%20to%20it%20%3A)%3C%2Fimg%3E%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22SignUp.png%22%20style%3D%22width%3A%20241px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F240107i07730500C0838E23%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22SignUp.png%22%20alt%3D%22Azure%20AD%20B2C%20SignUp%22%20%2F%3E%3CSPAN%20class%3D%22lia-inline-image-caption%22%20onclick%3D%22event.preventDefault()%3B%22%3EAzure%20AD%20B2C%20SignUp%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ENow%20this%20is%20a%20fairly%20stripped%20down%20sample%20app%20without%20the%20complexity%20of%20a%20real%20world%20app%2C%20but%20this%20was%20a%20rather%20pain%20free%20procedure%20for%20changing%20the%20identity%20engine%20in%20a%20web%20app.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1983575%22%20slang%3D%22en-US%22%3E%3CP%3EShort%20list%20of%20instructions%20for%20upgrading%20the%20identity%20implementation%20from%20using%20Azure%20AD%20B2C%20in%20a%20.NET%20Core%203.1%20app%20to%20using%20%3CEM%3EMicrosoft.Identity.Web%3C%2FEM%3E%20with%20.NET%205.%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1983575%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20Developer%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Senior Member

This year's release of .NET happened a few weeks ago with .NET 5. (Core is gone from the name now.) I have some sample code that works as sort of a boilerplate to verify basic functionality without containing anything fancy. One of those is a web app where one can sign in through Azure AD B2C. Logically I went ahead and updated from .NET Core 3.1 to .NET 5 to see if everything still works.

 

It works, but there are recommendations that you should put in some extra effort as the current NuGet packages are on their way to deprecation. Not like "will stop working in two weeks", but might as well tackle it now.

 

The Microsoft Identity platform has received an overhaul in parallel to .NET and a little while before the .NET 5 release the Identity team released Microsoft.Identity.Web packages for handling auth in web apps. (Not just for Azure AD B2C, but identity in general.)

 

Why is this upgrade necessary? Well, the old libraries were based on the Azure AD v1 endpoints, but these new libraries fully support the v2 endpoints. Which is great when going for full compliance with the OAuth and OpenID Connect protocols.

 

Using my sample at https://github.com/ahelland/Identity-CodeSamples-v2/tree/master/aad-b2c-custom_policies-dotnet-core  I wanted to do a test run from old to new.

 

The current code is using Microsoft.AspNetCore.Authentication.AzureADB2C.UI. (You can take a look at the code for the Upgraded to .NET 5 checkpoint for reference.)

 

You can start by using NuGet to download the latest version of Microsoft.Identity.Web and Microsoft.Identity.Web.UI. (1.4.0 when I'm typing this.) You can also remove Microsoft.AspNetCore.Authentication.AzureADB2C.UI while you're at it.

 

In Startup.cs you should make the following changes:

Replace

 

services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
  .AddAzureADB2C(options => Configuration.Bind("AzureADB2C", options)).AddCookie();

 

With

 

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureADB2C"));

 

 

And change

 

services.AddRazorPages(); 

 

To

 

services.AddRazorPages().AddMicrosoftIdentityUI();

 

 

If you have been doing "classic" Azure AD apps you will notice how B2E and B2C are now almost identical. Seeing how they both follow the same set of standards this makes sense. As well as making it easier for .NET devs to support both internal and external facing authentication.

 

B2C has some extra logic in the sense that the different policies drive you to different endpoints, so the UI has to have awareness of this. And you need to modify a few things in the views.

 

In LoginPartial.cshtml:

Change

 

@using Microsoft.AspNetCore.Authentication.AzureADB2C.UI
@using Microsoft.Extensions.Options
@inject IOptionsMonitor<AzureADB2COptions> AzureADB2COptions

@{
  var options = AzureADB2COptions.Get(AzureADB2CDefaults.AuthenticationScheme);   
}

 

To

 

@using Microsoft.Extensions.Options
@using Microsoft.Identity.Web
@inject IOptions<MicrosoftIdentityOptions> AzureADB2COptions

@{
  var options = AzureADB2COptions.Value;
}

 

 

And change the asp-area in links from using AzureADB2C:

 

<a class="nav-link text-dark" asp-area="AzureADB2C" asp-controller="Account" asp-action="SignOut">Sign out</a>

 

To using MicrosoftIdentity:

 

<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign out</a>

 

 

 

 

And that's all there is to it :)

Azure AD B2C SignUpAzure AD B2C SignUp

 

 

Now this is a fairly stripped down sample app without the complexity of a real world app, but this was a rather pain free procedure for changing the identity engine in a web app.