---
title: "Troubleshooting JwtBearer authentication issues in ASP.NET Core"
description: "How to troubleshoot JwtBearer authentication in ASP.NET Core APIs: 401 vs 403, middleware order, the WWW-Authenticate error details and the authentication logs."
url: https://nestenius.se/net/troubleshooting-jwtbearer-authentication-problems-in-asp-net-core/
date: 2023-02-21
author: "Tore Nestenius"
category: ".NET"
tags: ["authentication"]
site: https://nestenius.se/
---

# Troubleshooting JwtBearer authentication issues in ASP.NET Core

One of the most frequent questions I encounter on [Stack Overflow](https://stackoverflow.com/) is how to troubleshoot JwtBearer authentication issues in ASP.NET Core. In this post, I’ll share top tips and solutions to help you resolve common JwtBearer handler problems effectively.  

## **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 JwtBearer handler in the ASP.NET Core request pipeline](https://nestenius.se/_astro/jwtbearer-handler-1024x292.JYVu84qB_24t6d0.webp)

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:

![the purpose of the JwtBearer handler in ASP.NET Core](https://nestenius.se/_astro/authenticated-claims-principal-1024x465.BxfAcW8z_1SNRT1.webp)

## **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.

```csharp	
app.UseAuthentication();
app.UseAuthorization();
```

## **The JwtBearer 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
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:

```csharp			
.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
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:

- [WWW-Authenticate response header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/WWW-Authenticate)
- [RFC 7235 - Hypertext Transfer Protocol (HTTP/1.1): Authentication](https://datatracker.ietf.org/doc/html/rfc7235)  

## **Exploring the JwtBearer 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:

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

See [the ASP.NET Core logging documentation](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-7.0) for more details about how logging works.  

If I don’t have any logging infrastructure ready, I typically use [Serilog](https://serilog.net/) and send all my log entries to [Seq](https://datalust.co/seq) for further analysis.

## **JwtBearer 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](https://nestenius.se/net/debugging-jwtbearer-claim-problems-in-asp-net-core/) 

## **Conclusions**

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 on the [contact page](https://nestenius.se/contact/).

## Related posts

- [BearerToken: The new Authentication handler in .NET 8](https://nestenius.se/net/bearertoken-the-new-authentication-handler-in-net-8/)
- [Debugging JwtBearer Claim Problems in ASP.NET Core](https://nestenius.se/net/debugging-jwtbearer-claim-problems-in-asp-net-core/)
- [Debugging OpenID Connect claim problems in ASP.NET Core](https://nestenius.se/net/missing-openid-connect-claims-in-asp-net-core/)
- [IdentityServer – IdentityResource vs. ApiResource vs. ApiScope](https://nestenius.se/net/identityserver-identityresource-vs-apiresource-vs-apiscope/)

## Related Training Workshops 

- [Building ASP.NET Core APIs](https://tn-data.se/courses/building-asp-net-core-apis/)
- [ASP.NET Core fundamentals](https://tn-data.se/courses/asp-net-core-fundamentals/)
