using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Security.Cryptography; using Microsoft.IdentityModel.Tokens; using Tiku.Application.Security; using Tiku.Domain.Tenancy; namespace Tiku.IntegrationTests.Api; internal static class TestJwtKeys { public const string Issuer = "tiku-backend"; public const string Audience = "tiku-api"; public const string KeyId = "integration-test-rsa-key"; public static string PrivateKeyPem { get; } = CreatePrivateKeyPem(); public static string PublicKeyPem { get; } = CreatePublicKeyPem(); public static string CreateToken( IEnumerable claims, AuthRealm realm = AuthRealm.Tenant, bool includeStandardClaims = true, string? keyId = null) { using var rsa = RSA.Create(); rsa.ImportFromPem(PrivateKeyPem); var key = new RsaSecurityKey(rsa) { KeyId = keyId ?? KeyId, CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false } }; var credentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256); var tokenClaims = claims.ToList(); if (tokenClaims.All(claim => claim.Type != TikuClaimTypes.Realm)) { tokenClaims.Add(new Claim( TikuClaimTypes.Realm, realm.ToString().ToLowerInvariant())); } if (includeStandardClaims) { tokenClaims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N"))); tokenClaims.Add(new Claim( JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)); } var token = new JwtSecurityToken( Issuer, Audience, tokenClaims, expires: DateTime.UtcNow.AddMinutes(5), signingCredentials: credentials); return new JwtSecurityTokenHandler().WriteToken(token); } private static string CreatePrivateKeyPem() { using var rsa = RSA.Create(2048); return rsa.ExportPkcs8PrivateKeyPem(); } private static string CreatePublicKeyPem() { using var rsa = RSA.Create(); rsa.ImportFromPem(PrivateKeyPem); return rsa.ExportSubjectPublicKeyInfoPem(); } } internal sealed class TestJwtKeyRing : IJwtKeyRing { private static readonly RsaSecurityKey Key = CreateKey(); public SigningCredentials SigningCredentials { get; } = new(Key, SecurityAlgorithms.RsaSha256); public IReadOnlyCollection ValidationKeys { get; } = [Key]; private static RsaSecurityKey CreateKey() { var rsa = RSA.Create(); rsa.ImportFromPem(TestJwtKeys.PrivateKeyPem); return new RsaSecurityKey(rsa) { KeyId = TestJwtKeys.KeyId, CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false } }; } }