asp.net-coreazure-ad-b2cmicrosoft.identity.web

How to configure multiple B2C policies with Microsoft.Identity.Web?


I want my application to accept signins from two different B2C user flows, using the same tenant and app registration. In other words, I want both of these links to allow me to sign in to my app.

I started with the Visual Studio template for a Blazor server app (though I get the same problem with a basic razor app) with Microsoft identity platform as the authentication type and simply changed the appsettings to put my B2C information.

"AzureAdB2C": {
  "Instance": "https://myapp.b2clogin.com",
  "ClientId": "00000000-0000-0000-0000-000000000000", //my client id
  "Domain": "myapp.onmicrosoft.com",
  "SignUpSignInPolicyId": "b2c_1_susi",
  "TenantId": "11111111-0000-0000-0000-000000000000" //my tenant id
},
"AzureAdB2CVIP": {
  "Instance": "https://myapp.b2clogin.com",
  "ClientId": "00000000-0000-0000-0000-000000000000", //my client id, same as AzureAdB2C
  "Domain": "myapp.onmicrosoft.com",
  "SignUpSignInPolicyId": "b2c_1_susi_vip",
  "TenantId": "11111111-0000-0000-0000-000000000000" //my tenant id
}

Then in Startup.cs in ConfigureServices, I changed the setting name:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C"));
services.AddControllersWithViews()
    .AddMicrosoftIdentityUI();

As expected, when I run my app I get redirected to my b2c_1_susi policy to sign in and it connects just fine.
Now I want to add b2c_1_susi_vip. It doesn't need to be the default one but my application should also accept it. After trying several methods I've found, the least broken I got is like this:

var auth = services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme);
auth.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2CVIP"));
auth.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C"), cookieScheme: "authvip", openIdConnectScheme: "");

It redirects me to b2c_1_susi and at least works with that policy but trying to sign in with b2c_1_susi_vip results in Error from RemoteAuthentication: IDX10501: Signature validation failed.

I pretty much always end up with either the signature error or an error about the message.State being null or empty/unable to be read.

Methods I've tried without success

Is this seemingly simple scenario not possible?


Solution

  • I never could get my user flow and my custom policy to work together so I remade my user flow as a custom policy. Then I used this answer as a starting point for my solution.

    1. I created a MyAccountController with a SignUpVip action that's just a copy of Microsoft' signup action, but I set properties.Items["policy"] = "b2c_1_susi_vip";
    2. In my B2C page template, I added a link to mywebapp.com/MicrosoftIdentity/MyAccount/SignUpVip. This correctly redirects the user to the b2c_1_susi_vip policy with a valid state parameter and sets ASPnet's correlation cookie.
    3. I removed the 2nd call to AddMicrosoftIdentityWebApp.