w4c-workflows-api/Services/JwtValidator.cs

50 lines
1.7 KiB
C#

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
namespace w4c_workflows.Services;
/// <summary>
/// Validates the main w4c JWT (signed with the shared Auth:JwtSigningKey) and
/// extracts the tenant id. Used exclusively by the /api/keys* surface so a
/// logged-in tenant can mint/rotate/revoke its own operator keys.
/// </summary>
public static class JwtValidator
{
static JwtValidator()
{
// Keep inbound claims exactly as issued ("tenant_id", "sub", ...).
// JwtSecurityTokenHandler remaps claims to WS-Federation URIs by
// default, which makes FindFirstValue("tenant_id") return null.
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
}
public static ClaimsPrincipal? Validate(string? authHeader, string signingKey)
{
if (string.IsNullOrEmpty(signingKey) || string.IsNullOrEmpty(authHeader) ||
!authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
return null;
try
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey));
return new JwtSecurityTokenHandler().ValidateToken(
authHeader["Bearer ".Length..].Trim(),
new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(1),
}, out _);
}
catch
{
return null;
}
}
}