49 lines
1.9 KiB
C#
49 lines
1.9 KiB
C#
using System.Linq;
|
|
using System.Security.Claims;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using AS400API.Auth;
|
|
using AS400API.Configuration;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Routing;
|
|
|
|
namespace AS400API.Endpoints;
|
|
|
|
public static class AuthEndpoints
|
|
{
|
|
public static RouteGroupBuilder MapAuthEndpoints(this RouteGroupBuilder group)
|
|
{
|
|
group.MapPost("/v1/auth/login", async Task<IResult> (LoginRequest request, DemoUserStore userStore, TokenService tokenService, JwtOptions jwtOptions) =>
|
|
{
|
|
if (request is null || string.IsNullOrWhiteSpace(request.Username) || string.IsNullOrWhiteSpace(request.Password))
|
|
{
|
|
return Results.BadRequest(new { error = "Username and password are required." });
|
|
}
|
|
|
|
var user = await userStore.FindByNameAsync(request.Username);
|
|
if (user is null || !userStore.ValidateCredentials(user, request.Password))
|
|
{
|
|
return Results.Unauthorized();
|
|
}
|
|
|
|
var accessToken = tokenService.CreateToken(user);
|
|
return Results.Ok(new LoginResponse(accessToken, jwtOptions.AccessTokenLifetimeMinutes * 60, "Bearer", user.Roles));
|
|
})
|
|
.AllowAnonymous()
|
|
.WithSummary("Exchange credentials for a JWT access token")
|
|
.Produces<LoginResponse>(StatusCodes.Status200OK)
|
|
.Produces(StatusCodes.Status400BadRequest)
|
|
.Produces(StatusCodes.Status401Unauthorized);
|
|
|
|
group.MapGet("/v1/users/me", (ClaimsPrincipal user) =>
|
|
{
|
|
var username = user.Identity?.Name ?? user.FindFirstValue(JwtRegisteredClaimNames.Sub) ?? "unknown";
|
|
var roles = user.FindAll(ClaimTypes.Role).Select(r => r.Value).ToArray();
|
|
return Results.Ok(new { username, roles });
|
|
})
|
|
.RequireAuthorization()
|
|
.WithSummary("Returns the current user's profile from the access token");
|
|
|
|
return group;
|
|
}
|
|
}
|