초기커밋
This commit is contained in:
150
UGQApiServer/JWT/TokenService.cs
Normal file
150
UGQApiServer/JWT/TokenService.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
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 UGQApiServer.Settings;
|
||||
using UGQDatabase.Models;
|
||||
|
||||
|
||||
namespace JwtRoleAuthentication.Services;
|
||||
|
||||
public class TokenService
|
||||
{
|
||||
readonly JWTSettings _jwtSettings;
|
||||
|
||||
public TokenService(IOptions<JWTSettings> settings)
|
||||
{
|
||||
_jwtSettings = settings.Value;
|
||||
}
|
||||
|
||||
public string CreateToken(string userGuid, string nickname)
|
||||
{
|
||||
var token = CreateJwtToken(CreateClaims(userGuid, nickname));
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
public string CreateAdminToken(string username, UGQAccountRole role)
|
||||
{
|
||||
var token = CreateJwtToken(CreateAdminClaims(username, role));
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
public string GenerateRefreshToken()
|
||||
{
|
||||
var randomNumber = new byte[32];
|
||||
using var rng = RandomNumberGenerator.Create();
|
||||
rng.GetBytes(randomNumber);
|
||||
return Convert.ToBase64String(randomNumber);
|
||||
}
|
||||
|
||||
public ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
|
||||
{
|
||||
var tokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateAudience = false, //you might want to validate the audience and issuer depending on your use case
|
||||
ValidateIssuer = false,
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Secret)),
|
||||
ValidateLifetime = false //here we are saying that we don't care about the token's expiration date
|
||||
};
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
SecurityToken securityToken;
|
||||
var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out 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 GenerateAccessTokenFromRefreshToken(string refreshToken, string secret)
|
||||
{
|
||||
// Implement logic to generate a new access token from the refresh token
|
||||
// Verify the refresh token and extract necessary information (e.g., user ID)
|
||||
// Then generate a new access token
|
||||
|
||||
// For demonstration purposes, return a new token with an extended expiry
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var key = Encoding.ASCII.GetBytes(secret);
|
||||
|
||||
var tokenDescriptor = new SecurityTokenDescriptor
|
||||
{
|
||||
Expires = DateTime.UtcNow.AddMinutes(15), // Extend expiration time
|
||||
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
|
||||
};
|
||||
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
private JwtSecurityToken CreateJwtToken(List<Claim> claims)
|
||||
{
|
||||
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Secret));
|
||||
DateTime expiration = DateTime.UtcNow.AddMinutes(_jwtSettings.TokenValidityInMinutes);
|
||||
|
||||
return new(
|
||||
_jwtSettings.ValidIssuer,
|
||||
_jwtSettings.ValidAudience,
|
||||
claims,
|
||||
expires: expiration,
|
||||
signingCredentials: new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256)
|
||||
);
|
||||
}
|
||||
|
||||
private List<Claim> CreateAdminClaims(string username, UGQAccountRole role)
|
||||
{
|
||||
try
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
// new Claim(JwtRegisteredClaimNames.Sub, jwtSub),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()),
|
||||
new Claim(ClaimTypes.Name, username),
|
||||
new Claim(ClaimTypes.Role, role.ToString())
|
||||
};
|
||||
|
||||
return claims;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Claim> CreateClaims(string userGuid, string nickname)
|
||||
{
|
||||
try
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
// new Claim(JwtRegisteredClaimNames.Sub, jwtSub),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()),
|
||||
new Claim("Id", userGuid),
|
||||
new Claim(ClaimTypes.Name, nickname),
|
||||
// new Claim(ClaimTypes.Email, user.Email),
|
||||
// new Claim(ClaimTypes.Role, user.Role.ToString())
|
||||
};
|
||||
|
||||
return claims;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user