[Bug] SecurityTokenInvalidIssuerException when using B2C Login with AAD as a federated IdP
See original GitHub issueWhich Version of Microsoft Identity Web are you using ? Microsoft.Identity.Web 0.1.3-preview
Where is the issue?
- Web App
- Sign-in users
- Sign-in users and call web APIs
- Web API
- Protected web APIs (Validating tokens)
- Protected web APIs (Validating scopes)
- Protected web APIs call downstream web APIs
- Token cache serialization
- In Memory caches
- Session caches
- Distributed caches
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.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:6
- Comments:6
Top GitHub Comments
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://<myb2ctenant>.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.
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.