Troubleshooting JwtBearer authentication problems in ASP.NET Core

Troubleshooting JwtBearer authentication problems in ASP.NET Core

A common question that I help developers with on Stack Overflow is how to troubleshoot authentication problems when using the JwtBearer handler. Here I provide some of the best tips from my answers on Stack Overflow

The JwtBearer handler

We add the JwtBearer handler to the authentication middleware in our ASP.NET Core request pipeline, as shown in the picture below:

The main purpose of this handler is to look for an access token in the incoming HTTP request and if it is found, create an authenticated ClaimsPrincipal user instance, as shown below:

Troubleshooting JwtBearer authentication problems

The first thing to look at is the status code that is returned in the response from your API, as it will guide you to where to start looking for the problem.

  • 401 Unauthorized
    This error is typically generated by the JwtBearer handler, and it means that the incoming token is not found, valid or accepted.
  • 403 Forbidden
    This error is returned if the token is accepted but the user is not authorized to access the API resource. The authorization handler typically generates this error, and a common problem here is that the user object does not contain some of the required claims. Debugging authorization problems are not covered in this blog post.

If you get other status codes, this means it is likely that problem is elsewhere. Such as, 400 bad request or 500 server error.

Verify the order of the middleware modules.

The next thing is to ensure that the order of the authentication and authorization middleware in your request pipeline is correct. You must do authentication before you can do authorization.



The WWW-Authenticate header

If you have verified that the returned status code is 401, then the next step is to look at the WWW-Authenticate response header.

By default, the JwtBearer handler will include a WWW-Authenticate header in the response, as shown below:

					HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer 


By default, this header does not say that much, but you can get a more detailed error message by setting the IncludeErrorDetails flag to true, as shown below:

					 .AddJwtBearer(opt =>
    opt.IncludeErrorDetails = true;


Enabling this flag will result in that a more detailed error message in the WWW-Authenticate header, as shown below:

					HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"


Most of the time, this can give you a good clue about the source of the problem.

Don’t forget to make sure this flag is set to false in production, as it might otherwise leak clues to an attacker attacking your API.

You can read more about the purpose of this header here:


Exploring the logs

If the previous steps did not identify the problem, then the next step is to look at the log statements generated by the authentication and authorization middleware in ASP.NET Core.

If you manage your logging in appsettings.json files, then you can add and lower the logging levels to debug or trace, like this:

 "Logging": {
	"LogLevel": {
  	"Default": "Information",
  	"Microsoft": "Warning",
  	"Microsoft.Hosting.Lifetime": "Information",
      "Microsoft.AspNetCore.Authentication": "debug",
      "Microsoft.AspNetCore.Authorization": "debug"


Follow this link for more details about how logging works in ASP.NET Core.

If I don’t have any logging infrastructure ready, I typically use Serilog and send all my log entries to Seq for further analysis.

Claim problems

If you have problems with your User or Claims, then head over to my blog post Debugging JwtBearer Claim Problems in ASP.NET Core 


I hope the steps outlined above can help you troubleshoot your APIS and If you have any suggestions for this blog post, feedback, or questions on this blog post or would like to get in touch, you can find my contact details here.


About the author

Hi, I’m Tore! I have been fascinated by computers since I unpacked my first Commodore VIC-20. Today, I enjoy providing freelance development and developer training services, focusing on ASP.NET Core, IdentityServer, OpenID Connect, Architecture, and Web Security. You can connect with me on LinkedIn and Twitter, and you can find out more about me and my services here, as well as my classes for developers, including my course, Introduction to IdentityServer and OpenID-Connect.


Other posts by me:

Share This Story
Share on linkedin
Share on twitter
Share on facebook
Share on pinterest
Share on email

About me

My name is Tore Nestenius and I’m a trainer and senior software developer focusing on Architecture, Security and Identity, .NET, C#, Backend, and Cloud, among other things.

Do You Want Tore To Be Your Mentor?