Files
tiku-backend.net/Tiku.IntegrationTests/Api/TestJwtKeys.cs
xiong c497a3ca8d
Some checks failed
ci / release-gate (push) Has been cancelled
清理代码
2026-08-03 12:31:39 +08:00

96 lines
3.0 KiB
C#

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<Claim> 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<SecurityKey> 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
}
};
}
}