98 lines
3.7 KiB
C#
98 lines
3.7 KiB
C#
using Microsoft.AspNetCore.Mvc.Filters;
|
|
|
|
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Claims;
|
|
using System.Text;
|
|
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
using ServerCore;
|
|
|
|
namespace BrokerApiServer;
|
|
|
|
using BrokerApiCore;
|
|
|
|
/// <summary>
|
|
/// 엑세스 토큰 인증이 필요한 컨트롤러를 지정하는 애노테이션(Attribute) 정의
|
|
/// 밴 상태 체크 이슈
|
|
/// </summary>
|
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
|
public class RequireAdminAuthAttribute : System.Attribute, IAsyncActionFilter
|
|
{
|
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
|
{
|
|
// require 서비스 가져오기
|
|
// var planet_service = context.HttpContext.RequestServices.GetRequiredService<PlanetService>();
|
|
// Guard.Against.isNull(planet_service, ServerErrorCode.InternalServerError, "PlanetService가 di에 등록돼 있지 않음");
|
|
|
|
var auth_header = context.HttpContext.Request.Headers.Authorization.FirstOrDefault() ?? string.Empty;
|
|
Guard.Against.isNullOrEmptyOrWhiteSpace(auth_header, ServerErrorCode.InvalidPlanetJwt, ()=>"empty jwt");
|
|
Guard.Against.isFalse(auth_header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase),
|
|
ServerErrorCode.InvalidUserJwt, ()=>"인증 토큰 오류");
|
|
|
|
// "Bearer " 이후의 토큰 부분을 추출합니다.
|
|
var token = auth_header["Bearer ".Length..].Trim();
|
|
context.HttpContext.Items["admin_id"] = validate(token);
|
|
await next();
|
|
}
|
|
|
|
//==========================================
|
|
// secret_key: '81b659967735aea6e4cb0467d04ea12c4a6432b415254f59825055680f59a9823fec5a15e9adbd246b1365ef1522580477691bc5cb56a9364143e7d9385d9912'
|
|
// jdbc-url: jdbc:mysql://10.20.20.8:3306/caliverse?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
|
|
// username: external_ro
|
|
// password: bQNEXbRWQTtV6bwlqktGyBiuf2KqYF
|
|
// token
|
|
// eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJiZW9tY2h1bC5qYW5nQGxvdHRlLm5ldCIsImlhdCI6MTcyOTc1MzkzNiwiZXhwIjoxNzI5ODQwMzM2fQ.TzLFPigDZIYkxZa3JNdE2kHPxTBkCevwqtcWgz8tMnA
|
|
//==========================================
|
|
// todo: admin 관련 시크릿을 config에서 정의하여 사용할 것
|
|
private string validate(string jwt)
|
|
{
|
|
const string admin_pass_token = "p8qcZBraFCGfm2QeIGkJBynb6ULKhi6wGlnCDXvKTnM";
|
|
if (jwt == admin_pass_token)
|
|
{
|
|
return "park.chanheon@lotte.net";
|
|
}
|
|
|
|
var principal = parseToken(jwt);
|
|
Guard.Against.isNull(principal, ServerErrorCode.InvalidUserJwt, ()=>"jwt parsing error");
|
|
|
|
// var exp_time = DateTimeOffset.FromUnixTimeSeconds(long.Parse(exp_claim ?? string.Empty));
|
|
// Guard.Against.isFalse(exp_time > DateTimeOffset.UtcNow, ServerErrorCode.ExpiredPlanetJwt, "Jwt has expired");
|
|
return principal.FindFirstValue(JwtRegisteredClaimNames.Sub) ?? string.Empty;
|
|
}
|
|
|
|
public ClaimsPrincipal? parseToken(string token)
|
|
{
|
|
const string admin_secret_key = "81b659967735aea6e4cb0467d04ea12c4a6432b415254f59825055680f59a9823fec5a15e9adbd246b1365ef1522580477691bc5cb56a9364143e7d9385d9912";
|
|
var token_handler = new JwtSecurityTokenHandler();
|
|
|
|
// 시크릿 키를 바이트 배열로 변환
|
|
var key = Encoding.UTF8.GetBytes(admin_secret_key);
|
|
|
|
// 토큰 검증 매개변수 설정
|
|
var validation_parameters = new TokenValidationParameters
|
|
{
|
|
ValidateIssuer = false,
|
|
ValidateAudience = false,
|
|
ValidIssuer = "",
|
|
ValidAudience = "",
|
|
ValidateLifetime = true,
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKey = new SymmetricSecurityKey(key)
|
|
};
|
|
|
|
try
|
|
{
|
|
// 토큰 검증 및 클레임 추출
|
|
var principal = token_handler.ValidateToken(token, validation_parameters, out var validated_token);
|
|
return principal;
|
|
}
|
|
catch (SecurityTokenException ex)
|
|
{
|
|
Log.getLogger().error($"admin JWT 파싱 에러 => {ex.Message}");
|
|
}
|
|
return null;
|
|
}
|
|
}
|