I'm using Fastendpoints for my .NET8 project. I'm having an issue with change-password
endpoint.
public class ChangePasswordEndpoint : Endpoint<ChangePasswordRequest>
{
private readonly IAuthService _authService;
public ChangePasswordEndpoint(IAuthService authService) => _authService = authService;
public override void Configure()
{
Post("/auth/change-password");
Claims("UserId");
}
public override async Task HandleAsync(ChangePasswordRequest req, CancellationToken ct)
{
var userId = User.FindFirstValue("UserId");
req.UserId = Convert.ToInt32(userId);
await _authService.ChangePasswordAsync(req);
await SendOkAsync(ct);
}
}
Here is my Program.cs
var builder = WebApplication.CreateBuilder();
builder.Services
.AddFastEndpoints()
.AddJWTBearerAuth(builder.Configuration.GetSection("GeneralSettings:JwtSecret").Value)
.AddAuthorization();
builder.Services.SwaggerDocument();
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(builder.Configuration.GetSection("ConnectionStrings:DefaultConnection").Value), ServiceLifetime.Transient, ServiceLifetime.Transient);
builder.Services.AddIdentity<User, Role>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.RegisterServices();
builder.Services.ConfigureEmailSender(builder.Configuration);
builder.Services.ConfigureAppSettings(builder.Configuration);
var app = builder.Build();
app.UseAuthentication()
.UseAuthorization()
.UseFastEndpoints(c =>
{
c.Endpoints.RoutePrefix = "api";
c.Serializer.Options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
app.UseSwaggerGen();
app.UseStaticFiles();
app.ApplyPendingMigrations();
app.Run();
When I test this endpoint without Authorization header stated I always receive 404 as a response. The expected behavior would be to receive 401 if JWT is not entered. Other routes that are stated as anonymous work fine. Having this in mind, I'm guessing that I misconfiguration issue but I cannot figure out what I have done wrong.
for anybody else coming across this, the underlying cause is when multiple auth schemes are being used (jwt bearer & cookies) as done here due to the call to
.AddIdentity<>()
, cookie auth scheme becomes the default as it's registered last.the solution is to explicitly specify that the "change password" endpoint should only be authenticated via the jwt scheme like so:
more info can be found in this github issue.