Home > OS >  JWT token invalid token error using ASP.NET Core
JWT token invalid token error using ASP.NET Core

Time:07-08

I am creating an ASP.NET Core Web API. In this, I am using JWT token for authentication. I have created a demo SQL database for testing and I am testing my APIs using Fiddler. My ConfigureServices method of Startup class looks like this:

public void ConfigureServices(IServiceCollection services)
{
    var authPol = new AuthorizationPolicyBuilder()
                                             .AddAuthenticationSchemes(
                                                             new string[] { JwtBearerDefaults.AuthenticationScheme })
                                             .RequireAuthenticatedUser()
                                             .Build();
                          
    services.AddControllers(
                config => 
                {
                    config.Filters.Add(new AuthorizeFilter(authPol));
                }).AddXmlSerializerFormatters()
                .AddXmlDataContractSerializerFormatters();

    services.AddDbContext<BikeStoresContext>();

    // JWT Token
    var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("this-is-my-jwt-security-key"));

    var tokenValidationParameters = new TokenValidationParameters()
            {
                IssuerSigningKey = signingKey,
                ValidateIssuer = false,
                ValidateAudience = true,
                ClockSkew = TimeSpan.Zero
            };

    services.AddAuthentication(x => x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(jwt =>
                {
                    jwt.TokenValidationParameters = tokenValidationParameters;
                });

    services.AddIdentity<IdentityUser, IdentityRole>()
       .AddEntityFrameworkStores<BikeStoresContext>()
       .AddDefaultTokenProviders();

    services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "BikeStoreAPI", Version = "v1" });
            });
}

This is my JWT token generation code from Accounts controller's login action method:

var user = await userManager.FindByEmailAsync(model.UserEmail);
var roles = await userManager.GetRolesAsync(user);

IdentityOptions identityOptions = new IdentityOptions();
var claims = new Claim[]
                 {
                     new Claim("Lid", "123456789"),
                     new Claim(identityOptions.ClaimsIdentity.UserIdClaimType, user.Id),
                     new Claim(identityOptions.ClaimsIdentity.UserNameClaimType, user.UserName),
                     new Claim(identityOptions.ClaimsIdentity.RoleClaimType, roles[0]),
                     new Claim(identityOptions.ClaimsIdentity.EmailClaimType, user.Email)
                 };

var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("this-is-my-jwt-security-key"));
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

var jwt = new JwtSecurityToken(claims: claims, 
                    signingCredentials: signingCredentials, 
                    expires: DateTime.Now.AddMinutes(30));

return Ok(new
          {
              userName = model.UserEmail,
              role = roles[0],
              token = new JwtSecurityTokenHandler().WriteToken(jwt)
          });

JWT token is generated, but when I used the JWT token to access other APIs, I am getting this error.

WWW-Authenticate: Bearer error="invalid_token", error_description="The audience 'empty' is invalid"

I don't know where I made mistake in this code. Is there any change required?

Fiddler Screenshot:

enter image description here

CodePudding user response:

In the tokenValidationParameters you set ValidateAudience = true, which means that the aud-claim will be checked. But you never set a value for ValidAudience and also don't add an aud-claim to the token.

You can either turn off the check by setting

ValidateAudience = false

or add a ValidAudiencelike e.g:

ValidAudience = "your audience"

and add the aud-claim with:

var jwt = new JwtSecurityToken(claims: claims, 
                audience: "your audience",
                signingCredentials: signingCredentials, 
                expires: DateTime.Now.AddMinutes(30));
  • Related