186 lines
5.6 KiB
C#
186 lines
5.6 KiB
C#
// namespace BrokerCore.Services;
|
|
//
|
|
// using System.IdentityModel.Tokens.Jwt;
|
|
// using System.Security.Claims;
|
|
// using System.Security.Cryptography;
|
|
// using System.Text;
|
|
//
|
|
// using Microsoft.IdentityModel.Tokens;
|
|
//
|
|
// public interface IJwtUser
|
|
// {
|
|
// public string Id { get; }
|
|
// }
|
|
//
|
|
// public interface IJwtAuth
|
|
// {
|
|
//
|
|
// }
|
|
//
|
|
// public class RefreshToken
|
|
// {
|
|
// public int Id { get; set; }
|
|
// public string Token { get; set; } = string.Empty;
|
|
// public DateTime Created { get; set; } = DateTime.UtcNow;
|
|
// public DateTime Expires { get; set; }
|
|
// public bool IsExpired => DateTime.UtcNow >= Expires;
|
|
// public DateTime? Revoked { get; set; }
|
|
// public bool IsActive => Revoked == null && !IsExpired;
|
|
// public string? ReplacedByToken { get; set; }
|
|
// public string? ReasonRevoked { get; set; }
|
|
// public int UserId { get; set; }
|
|
// public IJwtUser User { get; set; } = null!;
|
|
// }
|
|
//
|
|
// public interface IJwtService<in TUser, TAuth> where TUser : class
|
|
// {
|
|
// string generateJwtToken(TUser user, string secretKey, int expirationMinutes = 15);
|
|
// string generateRefreshToken();
|
|
// int? validateJwtToken(string token);
|
|
// Task<TAuth> refreshTokenAsync(string token, string ipAddress);
|
|
// Task revokeTokenAsync(string token, string ipAddress, string? reason = null);
|
|
// }
|
|
// public class JwtService: IJwtService<IJwtUser, IJwtAuth>
|
|
// {
|
|
// private string m_secret_key = string.Empty;
|
|
// private int m_expiration_minutes = 15;
|
|
// private string m_issuer = string.Empty;
|
|
// private string m_audience = string.Empty;
|
|
//
|
|
// public string generateJwtToken(IJwtUser user)
|
|
// {
|
|
// if (user == null)
|
|
// throw new ArgumentNullException(nameof(user));
|
|
//
|
|
// if (string.IsNullOrEmpty(m_secret_key))
|
|
// throw new ArgumentNullException(nameof(m_secret_key));
|
|
//
|
|
// if (m_expiration_minutes <= 0)
|
|
// throw new ArgumentOutOfRangeException(nameof(m_expiration_minutes), "Expiration minutes must be greater than zero.");
|
|
//
|
|
// var token_handler = new JwtSecurityTokenHandler();
|
|
// var key = Encoding.ASCII.GetBytes(m_secret_key);
|
|
//
|
|
// var claims = new List<Claim>
|
|
// {
|
|
// new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
|
// // new Claim(ClaimTypes.Name, user.Username),
|
|
// // new Claim(ClaimTypes.Email, user.Email)
|
|
// // 필요한 경우 추가 클레임 정의 (역할 등)
|
|
// };
|
|
//
|
|
// var token_descriptor = new SecurityTokenDescriptor
|
|
// {
|
|
// Subject = new ClaimsIdentity(claims),
|
|
// Expires = DateTime.UtcNow.AddMinutes(15), // 액세스 토큰 만료 시간 (짧게 설정)
|
|
// Issuer = string.Empty,
|
|
// Audience = string.Empty,
|
|
// SigningCredentials = new SigningCredentials(
|
|
// new SymmetricSecurityKey(key),
|
|
// SecurityAlgorithms.HmacSha256Signature)
|
|
// };
|
|
//
|
|
// var token = token_handler.CreateToken(token_descriptor);
|
|
// return token_handler.WriteToken(token);
|
|
// }
|
|
//
|
|
// public string generateRefreshToken()
|
|
// {
|
|
// var random_number = new byte[16];
|
|
// using var rng = RandomNumberGenerator.Create();
|
|
// rng.GetBytes(random_number);
|
|
// return Convert.ToBase64String(random_number);
|
|
// }
|
|
//
|
|
// public int? validateJwtToken(string token)
|
|
// {
|
|
// if (string.IsNullOrEmpty(token))
|
|
// return null;
|
|
//
|
|
// var token_handler = new JwtSecurityTokenHandler();
|
|
// var key = Encoding.ASCII.GetBytes(m_secret_key);
|
|
//
|
|
// try
|
|
// {
|
|
// token_handler.ValidateToken(token, new TokenValidationParameters
|
|
// {
|
|
// ValidateIssuerSigningKey = true,
|
|
// IssuerSigningKey = new SymmetricSecurityKey(key),
|
|
// ValidateIssuer = true,
|
|
// ValidIssuer = this.m_issuer,
|
|
// ValidateAudience = true,
|
|
// ValidAudience = this.m_audience,
|
|
// // 시간 검증 설정
|
|
// ValidateLifetime = true,
|
|
// ClockSkew = TimeSpan.Zero
|
|
// }, out SecurityToken validated_token);
|
|
//
|
|
// var jwt_token = (JwtSecurityToken)validated_token;
|
|
// var user_id = int.Parse(jwt_token.Claims.First(x => x.Type == ClaimTypes.NameIdentifier).Value);
|
|
//
|
|
// return user_id;
|
|
// }
|
|
// catch
|
|
// {
|
|
// // 토큰 검증 실패
|
|
// return null;
|
|
// }
|
|
// }
|
|
//
|
|
// public Task<IJwtAuth> refreshTokenAsync(string token)
|
|
// {
|
|
// // 리프레시 토큰으로 유저 정보를 가져온다.
|
|
// var user;
|
|
//
|
|
// // 사용자가 없거나 토큰이 존재하지 않음
|
|
// if (user == null)
|
|
// throw new SecurityTokenException("Invalid token");
|
|
//
|
|
// var refreshToken = user.RefreshTokens.Single(x => x.Token == token);
|
|
//
|
|
// // 토큰이 더 이상 활성 상태가 아니면 오류
|
|
// if (!refreshToken.IsActive)
|
|
// throw new SecurityTokenException("Invalid token");
|
|
//
|
|
// // 새 리프레시 토큰 생성
|
|
// var newRefreshToken = generateRefreshTokenEntity();
|
|
//
|
|
// // 이전 토큰 폐기
|
|
// refreshToken.Revoked = DateTime.UtcNow;
|
|
// refreshToken.ReplacedByToken = newRefreshToken.Token;
|
|
// refreshToken.ReasonRevoked = "Replaced by new token";
|
|
//
|
|
// // 새 리프레시 토큰 추가
|
|
// user.RefreshTokens.Add(newRefreshToken);
|
|
// _context.Update(user);
|
|
// await _context.SaveChangesAsync();
|
|
//
|
|
// // 새 JWT 생성
|
|
// var jwtToken = generateJwtToken(user);
|
|
//
|
|
// return new
|
|
// {
|
|
// Id = user.Id,
|
|
// Username = user.Username,
|
|
// Email = user.Email,
|
|
// AccessToken = jwtToken,
|
|
// RefreshToken = newRefreshToken.Token
|
|
// };
|
|
// }
|
|
//
|
|
// public Task revokeTokenAsync(string token, string ipAddress, string? reason = null)
|
|
// {
|
|
// throw new NotImplementedException();
|
|
// }
|
|
//
|
|
// private RefreshToken generateRefreshTokenEntity()
|
|
// {
|
|
// return new RefreshToken
|
|
// {
|
|
// Token = generateRefreshToken(),
|
|
// Expires = DateTime.UtcNow.AddDays(32), // 리프레시 토큰 만료 시간 (길게 설정)
|
|
// Created = DateTime.UtcNow
|
|
// };
|
|
// }
|
|
// }
|