简体   繁体   中英

asp.net core AzureADJwtBearer issuer validation failure

I have the stock file | new | web | asp.net core web api project template where I selected AzureAD authentication that generated the following Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
        .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

and the following appsettings.json

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mymsdn.onmicrosoft.com",
    "TenantId": "<my azuread tenant id>",
    "ClientId": "<my azuread web app id>"
  }

I'm using postman to acquire token leveraging a public client profile app setup just as I have done for another web api setup that is working as expected with the same azureAd bearer token auth code and settings coordinates.

For some reason this app is trying to validate the wrong token issuer format and i'm at a loss as to how I correct it.

Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AzureADJwtBearer was not authenticated. Failure message: IDX10205: Issuer validation failed. Issuer: 'https://login.microsoftonline.com/<my azuread tenantid>/v2.0'. Did not match: validationParameters.ValidIssuer: 'null' or validationParameters.ValidIssuers: 'https://sts.windows.net/<my azuread tenantid>/'.

Turns out this issue surfaces if you configured azuread app registrations entry for your ClientId to support any organization or consumer, aka microsoft account, signins instead of just your organization or any organization. The fix was to use the AddJwtBearer() block of Startup.ConfigureServices() code shown below instead of the project template provided AddAzureADBearer() block.

public void ConfigureServices(IServiceCollection services)
{
    // if azuread app registrations entry for ClientId has "signInAudience": "AzureADMyOrg" or "AzureADMultipleOrgs" where "iss": "https://sts.windows.net/{TenantId}/"
    services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
        .AddAzureADBearer(options => //Configuration.Bind("AzureAd", options));
        {
            Configuration.Bind("AzureAd", options);
            Log.LogInformation($"the AddAzureADBearer options have been configured for ClientId = {options.ClientId}");
        });

    // if azuread app registrations entry for ClientId has "signInAudience": "AzureADandPersonalMicrosoftAccount" where "iss": "https://login.microsoftonline.com/{TenantId}/v2.0"
    services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; })
        .AddJwtBearer(options =>
        {
            var azureadoptions = new AzureADOptions(); Configuration.Bind("AzureAd", azureadoptions);
            options.Authority = $"{azureadoptions.Instance}{azureadoptions.TenantId}/v2";
            options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                ValidAudience = $"{azureadoptions.ClientId}",
                //ValidAudiences = new List<string> { $"{azureadoptions.ClientId}", $"api://{azureadoptions.ClientId}", $"https://myapp.azurewebsites.net/" },
                //ValidIssuer = $"https://sts.windows.net/{azureadoptions.TenantId}/" // for "signInAudience": "AzureADMyOrg" or "AzureADMultipleOrgs"
                ValidIssuer = $"{azureadoptions.Instance}{azureadoptions.TenantId}/v2.0" // for "signInAudience": "AzureADandPersonalMicrosoftAccount"
                //ValidIssuers = new List<string> { $"https://sts.windows.net/{azureadoptions.TenantId}/", $"{azureadoptions.Instance}{azureadoptions.TenantId}/v2.0" }                        
            };

            Log.LogInformation($"the AddJwtBearer options have been configured for ClientId = {azureadoptions.ClientId}");
        });
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

I was trying to authenticate existing token from uwp-app in web-api and I had a similar issue:

Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Failed to validate the token.

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10205: Issuer validation failed. Issuer: ' https://spolujizda.b2clogin.com/4e8094c9-5058-454c-b201-ef61d7ae6619/v2.0/ '. Did not match: validationParameters.ValidIssuer: 'null' or validationParameters.ValidIssuers: ' https://login.microsoftonline.com/4e8094c9-5058-454c-b201-ef61d7ae6619/v2.0/ '.

at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
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.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AzureADB2CJwtBearer was not authenticated. Failure message: IDX10205: Issuer validation failed. Issuer: ' https://spolujizda.b2clogin.com/4e8094c9-5058-454c-b201-ef61d7ae6619/v2.0/ '. Did not match: validationParameters.ValidIssuer: 'null' or validationParameters.ValidIssuers: ' https://login.microsoftonline.com/4e8094c9-5058-454c-b201-ef61d7ae6619/v2.0/ '. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "Get", controller = "Values"}. Executing action Spolujizda.ApiServer.Controllers.ValuesController.Get (Spolujizda.ApiServer) Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (). Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: AzureADB2CJwtBearer was challenged. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action Spolujizda.ApiServer.Controllers.ValuesController.Get (Spolujizda.ApiServer) in 8.105ms Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 8950.4739ms 401 text/plain

But for me the fix was much simpler.

For Web API I had AzureAdB2C.Instance set to https://spolujizda.b2clogin.com/tfp/ .

For an UWP app, I had been issuing token via https://login.microsoftonline.com/tfp/

That is why it resulted in this error. Because in the UWP app, the token was issued for login.microsoft ... and in the Web API, it was trying to verify issuer as spolujizda.b2clogin...

First I tried to change address for issuing token for uwp-app, but that didn't work.

So secondly I just changed web-api's AzureAdB2C.Instance config to login.microsoft.... and it now works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM