Common Errors in JWT Bearer Authentication
When implementing JWT Bearer authentication in an ABP(tiered) application, you might occasionally encounter errors starting with IDX. These errors are related to JWT Bearer Token validation and this article will help you understand and resolve them.
Enable JWT Bearer authentication
Your API project usually contains the following code, which enables JWT Bearer authentication and makes it as the default authentication scheme.
We simply configure the JWT's Authority and Audience properties, and it will work fine.
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://localhost:44301/"; //configuration["AuthServer:Authority"];
options.Audience = "MyProjectName";
});
AddJwtBearerandAddAbpJwtBearerwill do the same thing, butAddAbpJwtBeareris recommended.
JWT authentication process
Let's take a look at how the above code works.
A JWT Token usually consists of three parts: Header, Payload, and Signature.
Header: Contains the type and signing algorithm of the tokenPayload: Contains the claims of the token, includingsub,aud,exp,iat,iss,jti,preferred_username,given_name,role,email, etc.Signature: The cryptographic signature of the token used to verify its authenticity
Here is an example of a JWT Token issued by AuthServer(OpenIddict):
The Header part:

The Payload part:

TokenValidationParameters
In the JwtBearerOptions, there is a TokenValidationParameters property, which is used to validate the JWT Token.
The default implementation for JWT Token validation is JsonWebTokenHandler, which comes from the Microsoft.IdentityModel.JsonWebTokens package.
We didn't set the TokenValidationParameters property in the code above, so the default values below will be used:
//...
TokenValidationParameters.ValidateAudience = true
TokenValidationParameters.ValidAudience = "MyProjectName"
TokenValidationParameters.ValidAudiences = null
TokenValidationParameters.ValidateIssuer = true
TokenValidationParameters.ValidIssuer = null
TokenValidationParameters.ValidIssuers = null
//...
JWT Bearer Token Validation Process
During JWT Bearer authentication, API website will get the token from the HTTP request and validate it.
The JsonWebTokenHandler will get the OpenID Connect metadata from the AuthServer, it will be used in the validation process, the current metadata request address is: https://localhost:44301/.well-known/openid-configuration , it is a fixed address calculated from the Authority property.
First, the token's Signature is verified using the public key obtained from OpenID Connect metadata(https://localhost:44301/.well-known/jwks).
Then, the payload is validated. The payload is a JSON object containing essential information such as the token type, expiration time, issuer, and audience etc.
Most of the validation problems we may encounter are payload validation failures, for example:
Lifetime
If the token in your request has expired, the validation will fail. You will see the exception information like IDX10230 in the log.
Audience
The ValidAudience of TokenValidationParameters is MyProjectName, the aud in the payload of the token is also MyProjectName, if the token does not contain aud or the aud does not match, the validation will fail. You may see the exception information like IDX10206, IDX10277 or IDX10208.
If the
ValidateAudienceofTokenValidationParametersisfalse, then theaudwill not be validated.
Issuer
The default value of TokenValidationParameters.ValidateIssuer is true, it requires the token's payload to contain the issuer field, and it must match one of TokenValidationParameters.ValidIssuer or TokenValidationParameters.ValidIssuers.
The default value of
ValidIssuerorValidIssuersisnull, it will use theissuerfrom theOpenID Connectmetadata as the default value.
- If the token's payload does not contain the
issuerfield, you may see the errorIDX10211. - If the API website cannot get the
OpenID Connectmetadata from AuthServer website, the validation will fail. You may see the errorIDX10204, the full exception message is:IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty. - If the
issuerdoes not match, the validation will fail. You may see the errorIDX10205in the log.
If the
ValidateIssuerofTokenValidationParametersisfalse, then theissuerwill not be validated.
Please note that
OpenIddictwill use the current HTTP request information as the value ofissuer. If the AuthServer website is deployed behind a reverse proxy or similar deployment configurations, theissuerin the token may not be the value you expect. In this case, please specify it manually.
PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
{
serverBuilder.SetIssuer("https://localhost:44301/");
});
Troubleshooting
To troubleshoot any IDX errors during JWT authentication, you can enable detailed logging by configuring the identitymodel logs as follows:
using System.Diagnostics.Tracing;
using Microsoft.IdentityModel.Logging;
public class Program
{
public async static Task<int> Main(string[] args)
{
IdentityModelEventSource.ShowPII = true;
IdentityModelEventSource.Logger.LogLevel = EventLevel.Verbose;
var wilsonTextLogger = newTextWriterEventListener("Logs/identitymodel.txt");
wilsonTextLogger.EnableEvents(IdentityModelEventSource.Logger, EventLevel.Verbose);
//...
}
}
Additionally, you can enable OpenIddict's Verbose logs for more detailed debugging information:
var loggerConfiguration = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
.MinimumLevel.Override("OpenIddict", LogEventLevel.Verbose)
.Enrich.FromLogContext()
.WriteTo.Async(c => c.File("Logs/logs.txt"))
Summary
For JWT authentication, you need to pay attention to the following key points:
- Ensure your API website can communicate with the AuthServer properly
- Verify that the
audclaim in your token matches the expected audience - Confirm that the
issuerclaim in your token is valid and matches the configuration
You can customize the JwtBearerOptions's TokenValidationParameters to modify the validation rules to meet your actual needs.
For example, if your issuer needs to support multiple subdomains, you can use the Owl.TokenWildcardIssuerValidator library to customize the validation.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://abp.io";
options.Audience = "abp_io";
options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
options.TokenValidationParameters.ValidIssuers = new[]
{
"https://{0}.abp.io"
};
});
Comments
No one has commented yet, be the first to comment!