Bearer error - invalid_token - The signature key was not found
Asked Answered
R

13

42

I have an Angular 7 application interfacing with a .Net Core 2.2 API back-end. This is interfacing with Azure Active Directory.

On the Angular 7 side, it is authenticating properly with AAD and I am getting a valid JWT back as verified on jwt.io.

On the .Net Core API side I created a simple test API that has [Authorize] on it.

When I call this method from Angular, after adding the Bearer token, I am getting (as seen in Chrome Debug Tools, Network tab, "Headers"):

WWW-Authenticate: Bearer error="invalid_token", error_description="The signature key was not found"

With a HTTP/1.1 401 Unauthorized.

The simplistic test API is:

    [Route("Secure")]
    [Authorize]
    public IActionResult Secure() => Ok("Secure works");

The Angular calling code is also as simple as I can get it:

    let params : any = {
        responseType: 'text',
        headers: new HttpHeaders({
            "Authorization": "Bearer " + token,
            "Content-Type": "application/json"
        })
    }

    this.http
        .get("https://localhost:5001/api/azureauth/secure", params)
        .subscribe(
            data => { },
            error => { console.error(error); }
        );

If I remove the [Authorize] attribute and just call this as a standard GET request from Angular it works fine.

My Startup.cs contains:

        services
            .AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureADBearer(options => this.Configuration.Bind("AzureAd", options));

The options are all properly set (such as ClientId, TenantId, etc) in the appsettings.json and options here is populating as expected.

Rewrite answered 25/10, 2019 at 18:11 Comment(4)
How did you acquire the access token? Sounds like the token might be a Microsoft Graph API token.Scoop
@Scoop I have an application registered in Azure AD and have a ClientID, TenantID, and app-specific secret that are being passed to the proper endpoints as provided in the Azure management console. It's a valid JWT. It looks like this may end up being a conflict with an existing authorization scheme in the application. Working on that angle.Rewrite
Any luck on this? I am also facing the same issue.Forepaw
@PatrickI had same issue ? Did you find a solution ?Spavined
R
20

I was facing the same issue. i was missing the authority..make sure authority and api name is correct now this code in configure services in startup file works for me:

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication( x =>
                {
                    x.Authority = "http://localhost:5000"; //idp address
                    x.RequireHttpsMetadata = false;
                    x.ApiName = "api2"; //api name
                });
Recce answered 25/7, 2020 at 16:18 Comment(2)
Adding Authority saved my day! I use services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(x => { x.Authority = "<my_authority>"; }) and it does not work without Authority.Bentz
Isn't that using IdentityServer though on top of the JWT Bearer settings?Allotropy
G
8

I had a unique scenario, hopefully this will help someone.

I was building an API which has Windows Negotiate authentication enabled (.NET Core 5.0, running from IIS) and unit testing the API using the CustomWebApplicationFactory (see documentation for CustomWebApplicationFactory) through XUnit which does not support Negotiate authentication.

For the purposes of unit testing, I told CustomWebApplicationFactory to use a "UnitTest" environment (ASPNETCORE_ENVIRONMENT variable) and specifically coded logic into my application Startup.cs file to only add JWT authentication for the "UnitTest" environment.

I came across this error because my Startup.cs configuration did not have the signing key I used to create the token (IssuerSigningKey below).

if (_env.IsEnvironment("UnitTest"))
{
  // for unit testing, use a mocked up JWT auth, so claims can be overridden
  // for testing specific authentication scenarios
  services.AddAuthentication()
    .AddJwtBearer("UnitTestAuth", opt =>
    {
      opt.Audience = "api://local-unit-test";
      opt.RequireHttpsMetadata = false;
      opt.TokenValidationParameters = new TokenValidationParameters()
      {
        ClockSkew = TokenValidationParameters.DefaultClockSkew,
        ValidateAudience = true,
        ValidateIssuer = true,
        ValidateIssuerSigningKey = true,
        ValidAudience = "api://local-unit-test",
        ValidIssuer = "unit-test",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz123456"))
      };
    });
} else {
  // Negotiate configuration here...
}

Regardless of the ValidateIssuerSigningKey being true or false, I still received the "invalid_token" 401 response, same as the OP. I even tried specifying a custom IssuerSigningKeyValidator delegate to always override the result, but did not have luck with that either.

WWW-Authenticate: Bearer error="invalid_token", error_description="The signature key was not found"

When I added IssuerSigningKey to the TokenValidationParameters object (of course matching the key I used when generating the token in my unit test), everything worked as expected.

Goldsmith answered 15/7, 2021 at 16:13 Comment(3)
Upvote, thanks. Yeah I just had to add IssuerSigningKey and it worked.Ladida
Hi @TimTrewartha and 4e69636b, where did you get the IssuerSigningKey? I'm using Azure AD B2C.Katalin
Hi! I don't remember 🙈 Good luck!Ladida
V
4

My problem was that I needed to set the ValidIssuer option in the AddJwtBearer TokenValidationParameters, in addition to the authority

For example:

services.AddAuthentication("Bearer")
        .AddJwtBearer(options =>
        {
            options.Audience = "My Audience";
            options.Authority = "My issuer";
            options.TokenValidationParameters = new TokenValidationParameters {
                ValidateIssuerSigningKey = true,
                ValidateLifetime = true,
                ValidateIssuer = true,
                ValidIssuer = "Also My Issuer",    //Missing line here
                ValidateAudience = true
            };
        });
Virgilio answered 26/5, 2022 at 9:46 Comment(0)
G
3

The key when we generate the token:

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("this is my custom Secret key for authentication"));

Should be the same on DI:

IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("this is my custom Secret key for authentication"))
Goulette answered 6/7, 2023 at 18:40 Comment(0)
M
2

There could be two reason:

  1. You might have missed registering service :
services.AddAuthorization(auth =>
            {
                auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                    .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌​)
                    .RequireAuthenticatedUser().Build());
            });

Or 2. You might have missed assigning value to key "IssuerSigningKey" as shown below

validate.TokenValidationParameters = new TokenValidationParameters()
                                        {
                                            ValidateAudience = true,
                                            ValidAudience = "Audience",
                                            ValidateIssuer = true,
                                            ValidIssuer = "http://localhost:5000",
                                            RequireExpirationTime = false,
                                            ValidateIssuerSigningKey = true,
                                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("abcdefghi12345"))

                                        });

This resolved my problem

Mayday answered 28/9, 2021 at 19:58 Comment(1)
second one solved my problem, thanksAdd
F
0

My Core API uses different services configuration (and it works :)):

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddJwtBearer(options =>
  {
    Configuration.Bind("JwtBearer", options);
  }

Are you sure you are passing an access token and not an id_token? Is the aud claim present in the token exactly the same as the clientid your API is configured with? You may want to add some events to your options to see what you are receiving and where the validation fails.

Feldstein answered 25/10, 2019 at 19:56 Comment(2)
Access token is verified fine on jwt.io ... pasting my secret gets me a "Signature Verified". Decodes properly there. Perhaps I should switch to trying this with AddJwtBearer ... I am using Microsoft's library with AddAzureADBearer ... I assume options are the same. Do you have anything specified other than the default [Authorize] attribute on the secure API?Rewrite
No, just Authorize. I assume you mean 'pasting the public key', not 'pasting my secret', right? A token may have valid signature but not be for the API - is the aud claim same as what your API expects?Feldstein
M
0
  1. Verify the values that you send for request the jwt token (eg: grant_type, client_secret, scope, client_id, etc)
  2. Ensuere that you are using the appropiate token. That's all!

Here is my mistake: I was using Postman, and request a token and set it to a varibale "Var_Token1":

pm.environment.set("Var_Token1", pm.response.json().access_token);

But when I need to use the token for my final request, I selected and use the wrong token (Var_Token2):

Authorization: Bearer {{Var_Token2}}
Mesencephalon answered 13/6, 2020 at 6:5 Comment(0)
A
0

For me, this error was coming because the URL in appsettings.json was incorrect. I fixed it and it's working fine now.

Ardath answered 12/4, 2021 at 10:48 Comment(0)
O
0

This can also happen if you are using a different SignedOutCallbackPath/SignUpSignInPolicyId policy id than which is being passed in the token as tfp/acr.

Olivaolivaceous answered 16/9, 2021 at 10:57 Comment(0)
I
0

For me, the authority configured in the API must match the authority configured in the client including the http/https.

Ichinomiya answered 30/3, 2024 at 5:13 Comment(0)
T
0

After much struggle I found out the this "Microsoft.AspNetCore.Authentication.JwtBearer" that comes with the SDK is buggy. I had to reduce the version of this from "6.0.29" to "6.0.9" and this resolved the issue for me.

Toxicology answered 23/4, 2024 at 16:1 Comment(0)
U
0

I found this issue when upgrading my project from .NET 6 to .NET 8. On checking the logs, I found the same error mentioned here, and the fix provided here was helpful: IDX10500: Signature validation failed. No security keys were provided to validate the signature.

Pointing both of the following packages to the same version fixed the issue for me.

Microsoft.IdentityModel.JsonWebTokens and Microsoft.IdentityModel.Protocols.OpenIdConnect.

Univalve answered 10/7, 2024 at 7:8 Comment(0)
C
-2

I had this issue, and it was caused by jwtOptions.Authority not being set in config.

If you are using:

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme,

And jwtOptions.Authority is set to null or "" you can get this error message.

Calvano answered 2/6, 2020 at 8:48 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.