Skip to content

[question] Is it possible to add AzureAD *and* AzureAD B2C authentication to the same web app? #11972

Closed
@alexvy86

Description

@alexvy86

I've been struggling with this scenario for a bit and I'm starting to believe it might not be supported (at least in 2.2?), so I wanted to see if anyone can confirm that or point me on the right direction.

What I want to achieve is to allow different tenants in my multi-tenant application, to use different authentication providers (AzureAD for one, AzureAD B2C for another).

I'm registering separate schemes (Authentication, OpenID, Cookie, etc) for each tenant, like this (and similar for AzureAD):

var azureAdB2CConfigs = Configuration.GetSection("AzureAD_B2C").GetChildren();
foreach (var tenantSpecificConfig in azureAdB2CConfigs)
{
	var tenantName = tenantSpecificConfig.Key;
	services.AddAuthentication().AddAzureADB2C(
		Utils.GetTenantScopedScheme(AzureADB2CDefaults.AuthenticationScheme, tenantName),
		Utils.GetTenantScopedScheme(AzureADB2CDefaults.OpenIdScheme, tenantName),
		Utils.GetTenantScopedScheme(AzureADB2CDefaults.CookieScheme, tenantName),
		Utils.GetTenantScopedScheme(AzureADB2CDefaults.DisplayName, tenantName),
		options => tenantSpecificConfig.Bind(options));
}

If I only call AddAzureAD() or AddAzureADB2C() on the authentication builder, things work as expected. But if I call both, I start getting the error below when I make any request to my application (e.g. even just for the favicon). Of note, it doesn't happen immediately at startup, but only when I make the first request:

image

The order in which I register the AzureAD and AzureADB2C providers doesn't seem to matter.

I looked at the code for AddAzureAD() and AddAzureADB2C (for release/2.2) and I started suspecting that the issue comes from the fact that they both try to register singleton configurators for OpenIdConnectOptions (here and here), so maybe one of them isn't getting that object configured as it expects it to be. In master, those changed from TryAddSingleton to TryAddEnumerable (here and here). While I don't yet understand how each provider would get the correct OpenIdConnectOptions in this scenario, based on #4635 I imagine it might help...? @javiercn I hope it's not too intruding to tag you directly, but since you found the problem for #4635 and I think this might be similar I thought it might be useful to include you.

For completeness, this is the relevant section of my appsettings.json (which I believe is fine, because as I said, either AzureAD or AzureADB2C on its own works correctly).

"AzureAD": {
	"<tenant1>": {
		"Instance": "https://login.microsoftonline.com/",
		"Domain": "<tenant1-domain>.onmicrosoft.com",
		"TenantId": "organizations",
		"ClientId": "<tenant1-clientid>",
		"CallbackPath": "/signin-oidc"
	} 
},
"AzureAD_B2C": {
	"<tenant2>": {
		"Instance": "https://<tenant2-domain>.b2clogin.com/",
		"ClientId": "<tenant2-clientid>",
		"ClientSecret": "<secret>",
		"CallbackPath": "/b2c-signin-oidc",
		"Domain": "<tenant2-domain>.onmicrosoft.com",
		"SignUpSignInPolicyId": "B2C_1_SignUpOrSignIn"
	} 
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-authIncludes: Authn, Authz, OAuth, OIDC, Bearer

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions