In this .NET 8 project, generated JWT can authenticate in system, but fails to pass [Authorize(Roles = "user")]
and returns 403 Forbidden
As can be seen, JWT payload has role: "user":
";: "1",
"email": "[email protected] ",
";: "Arcturus Sky ",
";: "user ",
"nbf": 1743594643,
"exp": 1743595243,
"iss": "[email protected]",
"aud": "[email protected]"
}
Sample controller:
[Route("api/[controller]")]
[ApiController]
[Authorize(Roles = "user")]
public class ProductsController : ControllerBase
{
IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[HttpGet("getall")]
public IActionResult GetAll()
{
var result = _productService.GetAllProducts();
if (result.IsSuccess)
{
return Ok(result);
}
return BadRequest(result);
}
}
Here is how I config JWT in program.cs:
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Business.DependencyResolvers.Autofac;
using Core.Utilities.Security.JWT;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new AutofacBusinessModule());
});
TokenOptions tokenOptions = new TokenOptions();
builder.Configuration.GetRequiredSection(nameof(TokenOptions)).Bind(tokenOptions);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = tokenOptions.Issuer,
ValidAudience = tokenOptions.Audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecurityKey)),
ClockSkew = TimeSpan.Zero
};
});
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();
What is missing with implementation?
Also how this implementation could be improved, please guide me.
Thanks,