Use long
This commit is contained in:
@@ -12,7 +12,7 @@ public sealed class CurrentUser : IBindableFromHttpContext<CurrentUser>
|
|||||||
IsAuthenticated = isAuthenticated.HasValue && isAuthenticated.Value;
|
IsAuthenticated = isAuthenticated.HasValue && isAuthenticated.Value;
|
||||||
|
|
||||||
var rawId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
|
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;
|
Id = id;
|
||||||
|
|
||||||
Username = principal.FindFirstValue(ClaimTypes.Name);
|
Username = principal.FindFirstValue(ClaimTypes.Name);
|
||||||
@@ -24,7 +24,7 @@ public sealed class CurrentUser : IBindableFromHttpContext<CurrentUser>
|
|||||||
|
|
||||||
public bool IsAuthenticated { get; }
|
public bool IsAuthenticated { get; }
|
||||||
|
|
||||||
public Guid? Id { get; }
|
public long? Id { get; }
|
||||||
|
|
||||||
public string? Username { get; }
|
public string? Username { get; }
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ public sealed class CurrentUser : IBindableFromHttpContext<CurrentUser>
|
|||||||
|
|
||||||
public string? LastName { get; }
|
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);
|
public bool HasClaim(string type) => Principal.HasClaim(c => c.Type == type);
|
||||||
|
|
||||||
|
|||||||
@@ -5,21 +5,49 @@ using System.Security.Claims;
|
|||||||
|
|
||||||
namespace WebApi.Authentication;
|
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)
|
public override async Task TokenValidated(TokenValidatedContext tokenValidatedContext)
|
||||||
{
|
{
|
||||||
var principal = tokenValidatedContext.Principal!;
|
var principal = tokenValidatedContext.Principal!;
|
||||||
|
|
||||||
var id = principal.FindFirstValue(ClaimTypes.NameIdentifier)!;
|
var rawId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||||
var guidId = Guid.Parse(id);
|
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 firstName = principal.FindFirstValue(ClaimTypes.GivenName);
|
||||||
var lastName = principal.FindFirstValue(ClaimTypes.Surname);
|
var lastName = principal.FindFirstValue(ClaimTypes.Surname);
|
||||||
|
|
||||||
await mediator.Send(
|
try
|
||||||
new CreateUserCommand(guidId, username, firstName, lastName),
|
{
|
||||||
tokenValidatedContext.HttpContext.RequestAborted);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
namespace WebApi.DataTransferObjects.Users;
|
namespace WebApi.DataTransferObjects.Users;
|
||||||
|
|
||||||
public record CreateUserRequest(
|
public record CreateUserRequest(
|
||||||
Guid Id,
|
long Id,
|
||||||
string Name,
|
string Name,
|
||||||
string? FirstName,
|
string? FirstName,
|
||||||
string? SecondName);
|
string? SecondName);
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public static class PlayListEndpoints
|
|||||||
|
|
||||||
private static async Task<IResult> GetPlayListsByUserId(
|
private static async Task<IResult> GetPlayListsByUserId(
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
Guid userId,
|
long userId,
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
string? name,
|
string? name,
|
||||||
int pageNumber = 1,
|
int pageNumber = 1,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public static class TrackEndpoints
|
|||||||
|
|
||||||
private static async Task<IResult> GetTracksByUserId(
|
private static async Task<IResult> GetTracksByUserId(
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
Guid userId,
|
long userId,
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
string? name,
|
string? name,
|
||||||
int pageNumber = 1,
|
int pageNumber = 1,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public static class UserEndpoints
|
|||||||
|
|
||||||
private static async Task<IResult> GetUserById(
|
private static async Task<IResult> GetUserById(
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
Guid id,
|
long id,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await mediator.Send(new GetUserByIdQuery(id), cancellationToken);
|
var result = await mediator.Send(new GetUserByIdQuery(id), cancellationToken);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public sealed class ScalarOptionsSetup(IOptions<AuthenticationConfiguration> opt
|
|||||||
flow.Pkce = Pkce.Sha256;
|
flow.Pkce = Pkce.Sha256;
|
||||||
flow.SelectedScopes = _configuration.Scopes;
|
flow.SelectedScopes = _configuration.Scopes;
|
||||||
flow.RedirectUri = _configuration.ScalarRedirectUri;
|
flow.RedirectUri = _configuration.ScalarRedirectUri;
|
||||||
|
flow.RefreshUrl = _configuration.TokenEndpoint;
|
||||||
} )
|
} )
|
||||||
.HideModels();
|
.HideModels();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user