Files
Genesis_GameServer/GameServer/Services/PortfolioAdminAuth.cs
2026-09-03 19:18:46 +09:00

55 lines
2.0 KiB
C#

using System.Security.Cryptography;
using System.Text;
namespace GameServer.Services
{
/// <summary>
/// 포트폴리오 관리자 인증 도우미.
/// appsettings.json 의 Portfolio:AdminPassword 값을 읽어 비밀번호를 검증한다.
/// Program.cs 에서 싱글턴으로 등록된다.
/// </summary>
public class PortfolioAdminAuth
{
// 게임 API 와 섞이지 않도록 포트폴리오 전용 쿠키 인증 스킴을 사용한다.
public const string CookieScheme = "PortfolioAdminCookie";
// 관리자 전용 인가 정책 이름.
public const string PolicyName = "PortfolioAdmin";
// 비밀번호가 아직 설정되지 않았음을 뜻하는 기본 자리표시자 값.
private const string PlaceholderPassword = "CHANGE_ME";
private readonly string? _password;
public PortfolioAdminAuth(IConfiguration config)
{
_password = config["Portfolio:AdminPassword"];
}
/// <summary>
/// 실제 비밀번호가 설정되어 있는지 여부.
/// 값이 비어 있거나 자리표시자(CHANGE_ME) 그대로면 false.
/// </summary>
public bool IsConfigured =>
!string.IsNullOrWhiteSpace(_password) &&
!string.Equals(_password, PlaceholderPassword, StringComparison.Ordinal);
/// <summary>
/// 비밀번호를 상수 시간으로 비교한다. 미설정 상태면 언제나 false.
/// 길이 차이로 조기 종료되지 않도록 양쪽 모두 SHA-256 해시로 만든 뒤 비교한다.
/// </summary>
public bool Verify(string? password)
{
if (!IsConfigured)
{
return false;
}
byte[] expected = SHA256.HashData(Encoding.UTF8.GetBytes(_password!));
byte[] actual = SHA256.HashData(Encoding.UTF8.GetBytes(password ?? string.Empty));
return CryptographicOperations.FixedTimeEquals(expected, actual);
}
}
}