using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using SPMS.Application.Interfaces; using SPMS.Application.Settings; namespace SPMS.Infrastructure.Auth; public class JwtService : IJwtService { private readonly JwtSettings _settings; public JwtService(IOptions settings) { _settings = settings.Value; } public string GenerateAccessToken(long adminId, string role, string? serviceCode = null) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.SecretKey)); var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var claims = new List { new(JwtRegisteredClaimNames.Sub, adminId.ToString()), new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N")), new(ClaimTypes.Role, role), new("adminId", adminId.ToString()) }; if (!string.IsNullOrEmpty(serviceCode)) claims.Add(new Claim("ServiceCode", serviceCode)); var token = new JwtSecurityToken( issuer: _settings.Issuer, audience: _settings.Audience, claims: claims, expires: DateTime.UtcNow.AddMinutes(_settings.ExpiryMinutes), signingCredentials: credentials); return new JwtSecurityTokenHandler().WriteToken(token); } public ClaimsPrincipal? ValidateAccessToken(string token) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.SecretKey)); var validationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = _settings.Issuer, ValidAudience = _settings.Audience, IssuerSigningKey = key, ClockSkew = TimeSpan.Zero }; try { var handler = new JwtSecurityTokenHandler(); return handler.ValidateToken(token, validationParameters, out _); } catch { return null; } } public string GenerateRefreshToken() { var randomBytes = new byte[64]; using var rng = RandomNumberGenerator.Create(); rng.GetBytes(randomBytes); return Convert.ToBase64String(randomBytes); } public (string? Jti, DateTime ValidTo) GetTokenInfo(string token) { var handler = new JwtSecurityTokenHandler(); var jwtToken = handler.ReadJwtToken(token); return (jwtToken.Id, jwtToken.ValidTo); } }