Which Version of Microsoft Identity Web are you using ?
Microsoft.Identity.Web 0.1.3-preview
Where is the issue?
Is this a new or existing app?
This is a new app or experiment
I am using a custom policy (IEF) in AAD B2C to allow users to login using a specific corporate AAD Tenant instead of a local B2C account. The scenario is to support employee logins along side consumer logins.
I have implemented the custom policy as documented in Set up sign-in with an Azure Active Directory account using custom policies in Azure Active Directory B2C which is working as expected, with tokens being issued as required for both local users and Azure AD users.
However, when the token is returned to the web app, issuer validation is failing when the user logs in using AAD. When using a local account, it works as expected.
The issue is as a result of the tid claim not matching the AAD B2C Tenant ID, since the tid claim represents the Tenant ID that the user authenticated with.
The iss claim does, however, match the AAD B2C tenant.
Repro
Configure the custom policy as per the documentation linked above. Configure the web app as follows:
appsettings.json:
"AzureAdB2C": {
"Instance": "https://aad-b2c-tenant-name.b2clogin.com",
"ClientId": "00000000-0000-0000-0000-000000000000",
"Domain": "aad-b2c-tenant-name.onmicrosoft.com",
"SignedOutCallbackPath": "/signout/B2C_1A_signup_signin_employee",
"SignUpSignInPolicyId": "B2C_1A_signup_signin_employee",
"ResetPasswordPolicyId": "B2C_1A_PasswordReset",
"EditProfilePolicyId": "B2C_1A_ProfileEdit"
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
//SNIP
services.AddSignIn(Configuration, "AzureAdB2C");
//SNIP
}
When running the project, log in using the AAD Identity Provider instead of a local B2C account.
Expected behavior
Issuer validation should succeed and the user is logged in successfully.
Actual behavior
Token validation fails with an exception:
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[17]
Exception occurred while processing message.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: Issuer: 'https://aad-b2c-tenant-name.b2clogin.com/11111111-1111-1111-1111-111111111111/v2.0/', does not match any of the valid issuers provided for this application.
at Microsoft.Identity.Web.Resource.AadIssuerValidator.Validate(String actualIssuer, SecurityToken securityToken, TokenValidationParameters validationParameters) in C:\src\microsoft-identity-web\src\Microsoft.Identity.Web\Resource\AadIssuerValidator.cs:line 131
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateIssuer(String issuer, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.ValidateToken(String idToken, AuthenticationProperties properties, TokenValidationParameters validationParameters, JwtSecurityToken& jwt)
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()
For example, these might be the tenant IDs/Issuers
AAD B2C Tenant ID: 11111111-1111-1111-1111-111111111111
Corporate AAD Tenant ID: 22222222-2222-2222-2222-222222222222
tid Claim: 22222222-2222-2222-2222-222222222222
iss Claim: https://aad-b2c-tenant-name.b2clogin.com/11111111-1111-1111-1111-111111111111/v2.0/
Additional context/ Logs / Screenshots
Adding additional expected issuers has no effect. From debugging the code, I don't think this will help since it always uses the actual issuer (iss Claim) to compare with the tid Claim, and the issuer is always the AAD B2C domain, since the AAD login is federated.
@gjlumsden you might want to add several sections (one for the AAD, and add a AddSignIn for that section?
Thanks for your response, @jmprieur. I have tried to add an additional section for AAD and an additional AddSignIn call for the AAD section, but it results in an error on startup (System.InvalidOperationException: Scheme already exists: Cookies).
However, looking at the Microsoft.Identity.Web code again I don't see how this would help since the AAD IdP is federated from the AAD B2C IdP. Tokens will always be issued by the AAD B2C tenant. It won't be a case of the client deciding which IdP to navigate to.
Hopefully I've followed your recommendation correctly!
@gjlumsden, yes, you need to give other names for the schemes than the default ones.
AddSignIn, AddProtectedWebAPi etc ... have parameters with default values for the Scheme names. They need to be given an explicit value.
Oh, I had not understood that your AAD IdP was one of the identities of the B2C account.
Do you have a repro tenant? (you can email me if you wish: Jean-Marc dot prieur at microsoft dot com)
Any updates on this? I am having the same issue with the same scenario.
Code: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/1-WebApp-OIDC/1-5-B2C
Othe than that my scenario is exactly the same as above.
Okay, here is one possible fix for this problem:
https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/1-WebApp-OIDC/1-2-AnyOrg#how-to-restrict-users-from-specific-organizations-from-signing-in-your-web-app
It is necessary to adjust the if logic in the ValidateSpecificIssuers() - for example:
var validIssuers = GetAcceptedTenantIds();
if (validIssuers.Any(issuer.Contains))
The reason for this problem is, that in AadIssuerValidator.cs the _tenantId_ in the _actualIssuer_ variable ("https://
Ran to this same issue when using B2C with AD common endpoint sign in.
Luckily its not too hard to replace the IssuerValidator, but suboptimal user experience either way.
Most helpful comment
Okay, here is one possible fix for this problem:
https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/1-WebApp-OIDC/1-2-AnyOrg#how-to-restrict-users-from-specific-organizations-from-signing-in-your-web-app
It is necessary to adjust the if logic in the ValidateSpecificIssuers() - for example:
var validIssuers = GetAcceptedTenantIds();if (validIssuers.Any(issuer.Contains))The reason for this problem is, that in AadIssuerValidator.cs the _tenantId_ in the _actualIssuer_ variable ("https://.b2clogin.com/b2c-tenantId/v2.0/") is compared with a _tenantId_ (aad-tenantId) from the claim. This condition is always false and the reason for the error.