I am trying to implement a JWT authorization in my app and when I am trying to access the secured endpoint, I always get a http 404 error, instead of http 401.
Program.cs
:
using BusinessLogic.DataBasesContext;
using BusinessLogic.Interfaces;
using BusinessLogic.Services;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.EntityFrameworkCore;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using BusinessLogic.Models;
using Microsoft.AspNetCore.Identity;
//using Microsoft.AspNetCore.Identity;
var builder = WebApplication.CreateBuilder(args);
var key = Encoding.ASCII.GetBytes(builder.Configuration["Jwt:TokenKey"]);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
builder.Services.AddScoped<IVacationService, VacationService>();
builder.Services.AddScoped<IAccountService, AccountService>();
builder.Services.AddDbContext<VacationManagerDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true
};
});
builder.Services.AddIdentity<User, IdentityRole>(o =>
{
o.Password.RequireDigit = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.RequireUppercase = false;
o.Password.RequiredLength = 0;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
})
.AddEntityFrameworkStores<VacationManagerDbContext>()
.AddDefaultTokenProviders();
// CORS policy
builder.Services.AddCors(options =>
{
options.AddPolicy("ClientAPI",
policy =>
{
var allowedOrigins = builder.Configuration.GetSection("AllowedOrigins").Get<string[]>();
policy.WithOrigins(allowedOrigins)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors("ClientAPI");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Example endpoint:
using BusinessLogic.DTOs;
using BusinessLogic.Models;
using BusinessLogic.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authorization;
namespace VacationManagementAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class VacationsController : Controller
{
private readonly IVacationService _vacationService;
public VacationsController(IVacationService vacationService)
{
_vacationService = vacationService;
}
[HttpGet("{employeeEmail}")]
[ProducesResponseType(200, Type = typeof(IEnumerable<Vacation>))]
[ProducesResponseType(404)]
[Authorize]
public IActionResult GetEmployeeVacations(string employeeEmail)
{
var serviceResult = _vacationService.GetYoursEmployeeVacation(employeeEmail);
if (!serviceResult.Succeed)
return NotFound();
return Ok(serviceResult.Data);
}
}
}
Token creation:
private string GenerateJwtToken(User user)
{
var key = System.Text.Encoding.ASCII.GetBytes(_configuration["Jwt:TokenKey"]);
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, user.UserName),
new Claim(ClaimTypes.Email, user.Email)
}),
Expires = DateTime.UtcNow.AddHours(40),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature
)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
I have tried playing around with the JWT configs but nothing worked.
New contributor