using System.Security.Claims; using System.Security.Cryptography; using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Tokens; namespace OAuthServer.Services; public class JwtService { public readonly RSA RsaKey; public JwtService() { RsaKey = GetSigningKey(); } public static RSA GetSigningKey() { RSA rsaKey = RSA.Create(); const string jwtKeyPath = ".aspnet/jwt-key"; string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); string fullPath = Path.Combine(home, jwtKeyPath); if (File.Exists(fullPath)) { rsaKey.ImportRSAPrivateKey(File.ReadAllBytes(fullPath), out _); } else { string? dirName = Path.GetDirectoryName(fullPath); if (!string.IsNullOrEmpty(dirName)) Directory.CreateDirectory(dirName); var privateKey = rsaKey.ExportRSAPrivateKey(); File.WriteAllBytes(fullPath, privateKey); } return rsaKey; } public string GenerateToken(string audience, string? nonce) { var handler = new JsonWebTokenHandler(); var key = new RsaSecurityKey(RsaKey); var claims = new List { new(JwtRegisteredClaimNames.Iss, "http://localhost:1234"), new(JwtRegisteredClaimNames.Sub, "user1"), new(JwtRegisteredClaimNames.Aud, audience), new("role", "External"), new("scope", "scope:1"), }; if (nonce != null) { claims.Add(new Claim(JwtRegisteredClaimNames.Nonce, nonce)); } var token = handler.CreateToken(new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddDays(10), SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256) }); return token; } }