Search code examples
c#jwtpostmanasp.net-core-webapi.net-8.0

.NET8 ASP.NET Core Web API : JWT error : Bearer error="invalid_token"


I'm working on an ASP.NET Core 8 Web API project where I have to use JWT tokens. But I'm facing an error - no matter what I do. I'm able to generate tokens upon signin, but when I'm trying to use the generated token to call my weather controller, I get an error

Bearer error="invalid_token - 401 unauthorized

I have searched everywhere, tried my best to understand what's the issue..

This is my controller where I'm generating the tokens:

Initially Generated JWT Postman error upon HttpGet Request

[Route("[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
     [HttpPost("login")]
     public async Task<IActionResult> signIn(UserCred userDetails)
     {
         if (userDetails != null && userDetails.PhoneNumber != null && userDetails.Pin!= null)
         {
             UserDetails user = _user.GetUser(userDetails.PhoneNumber, userDetails.Pin);

             if (user != null)
             {
                 var claims = new[] 
                              {
                                  new Claim(JwtRegisteredClaimNames.Sub, _config["Jwt:Subject"]),
                                  new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                                  new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
                                  new Claim("UserId", user.Id),
                                  new Claim("DisplayName", user.FirstName),
                                  new Claim("UserName", user.LastName),
                                  new Claim("Email", user.Email)
                              };

                 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
                 var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                 var token = new JwtSecurityToken(_config["Jwt:Issuer"],
                                      _config["Jwt:Audience"],
                                      claims,
                                      expires: DateTime.UtcNow.AddMinutes(10),
                                      signingCredentials: signIn);

                 return Ok(new JwtSecurityTokenHandler().WriteToken(token));
             }
             else
             {
                  return BadRequest("Invalid credentials");
             }
        }
        else
        {
            return BadRequest();
        }
    }
}   

And here is program.cs for reference:

var builder = WebApplication.CreateBuilder(args);
var MyAllowSpecificOrigins = "_specificOrigin";
// Add services to the container.

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins, policy =>
    {
        policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
    });
});

builder.Services.AddControllers();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.RequireHttpsMetadata = false;
    options.SaveToken = true;
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidAudience = builder.Configuration["Jwt:Audience"],
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});

builder.Services.AddAuthorization();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(
    builder.Configuration.GetConnectionString("DefaultConnection")

));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

the Generated Token Works fine when I test on JWT debugger websites but dosent work on my API JWT Debugger Result

I'm really stuck here. Let me share the project's github repo, for reference: TechBuzzersBank API

I think the error is somewhere in my controller, but I'm unable to fix it. Maybe it's with the way I'm calling the API (in postman)?


Solution

  • Apparently, this issue occurs due to major changes in .NET 8

    and Here is the explaination.

    A quick fix I found was : adding

    options.UseSecurityTokenValidators = true;

    in

    builder.Services.AddAuthentication()

    helps. It did not work for me though ... I have decided to shift to .NET 6 for the current project. Ill update here if I find any other solution.