84 lines
2.6 KiB
C#
84 lines
2.6 KiB
C#
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.Extensions.Options;
|
|
using YarpGateway.Config;
|
|
|
|
namespace YarpGateway.Middleware;
|
|
|
|
public class JwtTransformMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly JwtConfig _jwtConfig;
|
|
private readonly ILogger<JwtTransformMiddleware> _logger;
|
|
|
|
public JwtTransformMiddleware(
|
|
RequestDelegate next,
|
|
IOptions<JwtConfig> jwtConfig,
|
|
ILogger<JwtTransformMiddleware> logger
|
|
)
|
|
{
|
|
_next = next;
|
|
_jwtConfig = jwtConfig.Value;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
|
|
if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer "))
|
|
{
|
|
await _next(context);
|
|
return;
|
|
}
|
|
|
|
var token = authHeader.Substring("Bearer ".Length).Trim();
|
|
|
|
try
|
|
{
|
|
var jwtHandler = new JwtSecurityTokenHandler();
|
|
var jwtToken = jwtHandler.ReadJwtToken(token);
|
|
|
|
var tenantId = jwtToken.Claims.FirstOrDefault(c => c.Type == "tenant")?.Value;
|
|
var userId = jwtToken
|
|
.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)
|
|
?.Value;
|
|
var userName = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
|
|
var roles = jwtToken
|
|
.Claims.Where(c => c.Type == ClaimTypes.Role)
|
|
.Select(c => c.Value)
|
|
.ToList();
|
|
|
|
if (!string.IsNullOrEmpty(tenantId))
|
|
{
|
|
context.Request.Headers["X-Tenant-Id"] = tenantId;
|
|
|
|
if (!string.IsNullOrEmpty(userId))
|
|
context.Request.Headers["X-User-Id"] = userId;
|
|
|
|
if (!string.IsNullOrEmpty(userName))
|
|
context.Request.Headers["X-User-Name"] = userName;
|
|
|
|
if (roles.Any())
|
|
context.Request.Headers["X-Roles"] = string.Join(",", roles);
|
|
|
|
_logger.LogInformation(
|
|
"JWT transformed - Tenant: {Tenant}, User: {User}",
|
|
tenantId,
|
|
userId
|
|
);
|
|
}
|
|
else
|
|
{
|
|
_logger.LogWarning("JWT missing tenant claim");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to parse JWT token");
|
|
}
|
|
|
|
await _next(context);
|
|
}
|
|
}
|