I have this ASP.NET Core 8 Web API project. I have an AuthenticationController
and I have a protected endpoint. It returns an error http 404 when I try to access it with token and without it.
I suspect there is a problem with the authentication schemas:
[Authorize]
[ApiController]
[Route("[controller]/[action]")]
public class ApartmentController : ControllerBase
{
private readonly IMediator _mediator;
public ApartmentController(IMediator mediator)
{
_mediator = mediator;
}
[HttpPost]
public async Task<IActionResult> Add([FromBody] AddApartmentDto dto)
{
var response = await _mediator.Send(new AddApartmentRequest(dto));
if (response.StatusCode == (int)HttpStatusCode.OK)
return Ok(new { id = response.Value });
return StatusCode(response.StatusCode, new { problem = response.Message });
}
[HttpGet]
[Route("/[controller]/{id:int}")]
public async Task<IActionResult> Get(int id)
{
var response = await _mediator.Send(new GetApartmentRequest(id));
if (response.StatusCode == (int)HttpStatusCode.OK)
return Ok(response.Value);
return StatusCode(response.StatusCode, new { problem = response.Message });
}
[HttpGet]
[Route("/[controller]/schedule/{id:int}")]
public async Task<IActionResult> GetSchedule(int id)
{
var response = await _mediator.Send(new GetScheduleRequest(id));
if (response.StatusCode == (int)HttpStatusCode.OK)
return Ok(response.Value);
return StatusCode(response.StatusCode, new { problem = response.Message });
}
[HttpPost]
[Route("/[controller]/schedule-viewing")]
public async Task<IActionResult> ScheduleViewing([FromBody] ScheduleViewingDto dto)
{
var response = await _mediator.Send(new ScheduleViewingRequest(dto));
if (response.StatusCode == (int)HttpStatusCode.OK)
return Ok(new { message = response.Message });
return StatusCode(response.StatusCode, new { problem = response.Message });
}
}
This is my Program.cs
file
...
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = config["JwtSettings:Issuer"],
ValidAudience = config["JwtSettings:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(config["JwtSettings:Key"]!)),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
RequireExpirationTime = true
};
});
//.AddOAuth();
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityContext>()
.AddDefaultTokenProviders();
builder.Services.Configure<IdentityOptions>(options =>
{
// Password settings
options.Password.RequireDigit = true;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 5;
options.Password.RequiredUniqueChars = 1;
// SignIn settings
options.SignIn.RequireConfirmedEmail = true;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(1);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.@_+";
options.User.RequireUniqueEmail = true;
});
builder.Services.AddAuthorization();
// .AddPolicy(nameof(Owner), policy => { policy.RequireRole(nameof(Owner)); })
// .AddPolicy(nameof(Customer), policy => { policy.RequireRole(nameof(Customer)); })
// .AddPolicy("Admin", policy => { policy.RequireRole("Admin"); });
...
builder.Services.AddInterfaceAdapters();
builder.Services.Configure<JwtSettings>(config.GetSection("JwtSettings"));
var app = builder.Build();
app.MapHealthChecks("/_health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
I tried to specify policies for the endpoint but it doesn't work.
You need to change your Authorize
attribute to [Authorize(AuthenticationSchemes = "Bearer")]
since you are using JWT authentication scheme.
What you encountering is happening because your API is not authorized and your redirect URL doesn't exist and hence a 404
not found is thrown. Also you should add the Identity
before Authentication
in your Program.cs