1
0

93 lines
3.4 KiB
C#

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Microsoft.IdentityModel.Tokens;
namespace Flawless.Server.Services;
public class TokenGenerationService
{
private readonly SymmetricSecurityKey _key;
private readonly string _issuer;
private readonly double _expiresIn;
private readonly double _refreshTokenLifeTime;
public TokenGenerationService(IConfiguration c)
{
var rawKey = Encoding.UTF8.GetBytes(c["Jwt:SecretKey"] ?? throw new Exception("No Jwt:SecretKey"));
_key = new SymmetricSecurityKey(rawKey);
_issuer = c["Jwt:Issuer"] ?? throw new Exception("No Jwt:Issuer");
_expiresIn = double.Parse(c["Jwt:ExpiresIn"] ?? throw new Exception("No Jwt:ExpiresIn"));
_refreshTokenLifeTime = double.Parse(c["Jwt:RefreshTokenLifeTime"] ?? throw new Exception("No Jwt:RefreshTokenLifeTime"));
}
public double RefreshTokenLifeTime => _refreshTokenLifeTime;
public string GenerateToken(IEnumerable<Claim> claims)
{
var now = DateTime.UtcNow;
var jwt = new JwtSecurityToken(
issuer: _issuer,
claims: claims,
notBefore: now,
expires: now.AddMinutes(_expiresIn),
signingCredentials: new SigningCredentials(_key, SecurityAlgorithms.HmacSha256)
);
return new JwtSecurityTokenHandler().WriteToken(jwt);
}
public ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
{
var tokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = true,
ValidateLifetime = false,
ValidateIssuerSigningKey = true,
ValidIssuer = _issuer,
IssuerSigningKey = _key,
};
var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out var securityToken);
var jwtSecurityToken = securityToken as JwtSecurityToken;
if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
throw new SecurityTokenException("Invalid token");
return principal;
}
public ClaimsPrincipal GetPrincipal(string token)
{
var tokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = _issuer,
IssuerSigningKey = _key,
};
var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out var securityToken);
var jwtSecurityToken = securityToken as JwtSecurityToken;
if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
throw new SecurityTokenException("Invalid token");
return principal;
}
public string GenerateRefreshToken()
{
Span<byte> randomNumber = stackalloc byte[32];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(randomNumber);
return Convert.ToBase64String(randomNumber);
}
}