85 lines
2.6 KiB
C#
85 lines
2.6 KiB
C#
using System.Security.Claims;
|
|
using line_gestao_api.Data;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace line_gestao_api.Services;
|
|
|
|
public class TenantMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
|
|
public TenantMiddleware(RequestDelegate next)
|
|
{
|
|
_next = next;
|
|
}
|
|
|
|
public async Task InvokeAsync(
|
|
HttpContext context,
|
|
ITenantProvider tenantProvider,
|
|
AppDbContext db)
|
|
{
|
|
Guid? tenantId = null;
|
|
|
|
// Usuário autenticado: tenant vem do token.
|
|
// Se token legado vier sem tenantId, tenta resolver pelo UserId no banco.
|
|
if (context.User.Identity?.IsAuthenticated == true)
|
|
{
|
|
var claim = context.User.FindFirst("tenantId")?.Value
|
|
?? context.User.FindFirst("tenant")?.Value;
|
|
|
|
if (Guid.TryParse(claim, out var parsedFromClaim) && parsedFromClaim != Guid.Empty)
|
|
{
|
|
tenantId = parsedFromClaim;
|
|
}
|
|
else
|
|
{
|
|
var userIdRaw = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
|
?? context.User.FindFirst("sub")?.Value;
|
|
|
|
if (Guid.TryParse(userIdRaw, out var userId))
|
|
{
|
|
var tenantFromUser = await db.Users
|
|
.AsNoTracking()
|
|
.IgnoreQueryFilters()
|
|
.Where(u => u.Id == userId)
|
|
.Select(u => (Guid?)u.TenantId)
|
|
.FirstOrDefaultAsync();
|
|
|
|
if (tenantFromUser.HasValue && tenantFromUser.Value != Guid.Empty)
|
|
{
|
|
tenantId = tenantFromUser.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Evita comportamento silencioso de "dados vazios" quando token não traz tenant válido.
|
|
if (!tenantId.HasValue)
|
|
{
|
|
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
|
await context.Response.WriteAsync("Tenant inválido.");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Usuário anônimo: permite header para fluxos como login multi-tenant.
|
|
var headerValue = context.Request.Headers["X-Tenant-Id"].FirstOrDefault();
|
|
if (Guid.TryParse(headerValue, out var headerTenant) && headerTenant != Guid.Empty)
|
|
{
|
|
tenantId = headerTenant;
|
|
}
|
|
}
|
|
|
|
tenantProvider.SetTenantId(tenantId);
|
|
|
|
try
|
|
{
|
|
await _next(context);
|
|
}
|
|
finally
|
|
{
|
|
tenantProvider.SetTenantId(null);
|
|
}
|
|
}
|
|
}
|