54 lines
2.0 KiB
C#
54 lines
2.0 KiB
C#
using System.Security.Claims;
|
|
using Aegis.Application.Abstractions;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
|
|
namespace Aegis.API.Auth;
|
|
|
|
public class UserResolutionMiddleware(RequestDelegate next, IMemoryCache cache)
|
|
{
|
|
// TTL do cache (ajuste como quiser)
|
|
private static readonly TimeSpan CacheTtl = TimeSpan.FromHours(1);
|
|
public async Task InvokeAsync(HttpContext ctx, IUserIdentityRepository repo, CancellationToken ct)
|
|
{
|
|
// Só roda para requests autenticadas
|
|
if (ctx.User?.Identity?.IsAuthenticated == true)
|
|
{
|
|
var sub = ctx.User.FindFirstValue("sub");
|
|
var iss = ctx.User.FindFirstValue("iss");
|
|
|
|
if (!string.IsNullOrWhiteSpace(sub) && !string.IsNullOrWhiteSpace(iss))
|
|
{
|
|
var cacheKey = $"aegis_uid|{iss}|{sub}";
|
|
|
|
if (!cache.TryGetValue(cacheKey, out string? userIdValue))
|
|
{
|
|
var displayName = ctx.User.FindFirstValue("name")
|
|
?? ctx.User.FindFirstValue("preferred_username");
|
|
|
|
var email = ctx.User.FindFirstValue("email");
|
|
|
|
var userId = await repo.GetOrCreateAsync(sub, iss, displayName, email, ct);
|
|
userIdValue = userId.Value;
|
|
|
|
cache.Set(
|
|
cacheKey,
|
|
userIdValue,
|
|
new MemoryCacheEntryOptions
|
|
{
|
|
AbsoluteExpirationRelativeToNow = CacheTtl,
|
|
SlidingExpiration = TimeSpan.FromMinutes(15)
|
|
});
|
|
}
|
|
|
|
// Injeta claim aegis_uid se não existir
|
|
if (ctx.User.FindFirst("aegis_uid") is null && userIdValue is not null)
|
|
{
|
|
if (ctx.User.Identity is ClaimsIdentity identity)
|
|
identity.AddClaim(new Claim("aegis_uid", userIdValue));
|
|
}
|
|
}
|
|
}
|
|
|
|
await next(ctx);
|
|
}
|
|
} |