This commit is contained in:
2026-05-31 18:25:40 +02:00
parent 1bd8bb4bd6
commit 1e06f60a1b
7 changed files with 43 additions and 14 deletions
+3 -3
View File
@@ -12,7 +12,7 @@ public sealed class CurrentUser : IBindableFromHttpContext<CurrentUser>
IsAuthenticated = isAuthenticated.HasValue && isAuthenticated.Value;
var rawId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
if (Guid.TryParse(rawId, out var id) && id != Guid.Empty)
if (long.TryParse(rawId, out var id) && id != 0)
Id = id;
Username = principal.FindFirstValue(ClaimTypes.Name);
@@ -24,7 +24,7 @@ public sealed class CurrentUser : IBindableFromHttpContext<CurrentUser>
public bool IsAuthenticated { get; }
public Guid? Id { get; }
public long? Id { get; }
public string? Username { get; }
@@ -32,7 +32,7 @@ public sealed class CurrentUser : IBindableFromHttpContext<CurrentUser>
public string? LastName { get; }
public Guid RequiredId => Id ?? throw new InvalidOperationException("User Id claim is missing or invalid.");
public long RequiredId => Id ?? throw new InvalidOperationException("User Id claim is missing or invalid.");
public bool HasClaim(string type) => Principal.HasClaim(c => c.Type == type);
@@ -5,21 +5,49 @@ using System.Security.Claims;
namespace WebApi.Authentication;
public sealed class JwtBearerEventsHandler(IMediator mediator) : JwtBearerEvents
public sealed class JwtBearerEventsHandler(IMediator mediator, ILogger<JwtBearerEventsHandler> logger) : JwtBearerEvents
{
public override async Task TokenValidated(TokenValidatedContext tokenValidatedContext)
{
var principal = tokenValidatedContext.Principal!;
var id = principal.FindFirstValue(ClaimTypes.NameIdentifier)!;
var guidId = Guid.Parse(id);
var rawId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
if (!long.TryParse(rawId, out var userId))
{
logger.LogWarning("Token subject '{Subject}' is not a numeric id; skipping user provisioning", rawId);
return;
}
var username = principal.FindFirstValue(ClaimTypes.Name)
?? principal.FindFirstValue("preferred_username")
?? principal.FindFirstValue(ClaimTypes.Email)
?? rawId!;
var username = principal.FindFirstValue(ClaimTypes.Name)!;
var firstName = principal.FindFirstValue(ClaimTypes.GivenName);
var lastName = principal.FindFirstValue(ClaimTypes.Surname);
await mediator.Send(
new CreateUserCommand(guidId, username, firstName, lastName),
tokenValidatedContext.HttpContext.RequestAborted);
try
{
await mediator.Send(
new CreateUserCommand(userId, username, firstName, lastName),
tokenValidatedContext.HttpContext.RequestAborted);
}
catch (Exception exception)
{
logger.LogError(exception, "Failed to provision user {UserId} during token validation", userId);
}
}
public override Task AuthenticationFailed(AuthenticationFailedContext context)
{
logger.LogWarning(context.Exception, "JWT authentication failed");
return Task.CompletedTask;
}
public override Task Challenge(JwtBearerChallengeContext context)
{
if (context.AuthenticateFailure is not null)
logger.LogWarning("JWT challenge: {Error} - {Description}", context.Error, context.ErrorDescription);
return Task.CompletedTask;
}
}