48. 장수명 연결의 인증·권한 만료 재검증 부재(만료 후 권한 유지) · C#

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 시나리오: 장수명 게임 세션의 인증·권한 만료 처리 (C#)
//
// 클라이언트는 접속 시 인증 토큰을 제시하고, 서버는 세션을 만들며 토큰의
// 만료 시각(ExpiresAtUtc)을 세션에 저장한다. 토큰은 계정 인증뿐 아니라
// 시간제 권한(예: 이번 세션에서 프리미엄 상점 접근 허용 만료 시각)도 담는다.
// 게임 세션은 몇 시간씩 유지될 수 있고(장수명 TCP 연결), 그동안 클라이언트는
// 여러 요청을 보낸다.
//
// 요구사항:
//  - 토큰이 만료되면 그 이후의 보호된 동작(프리미엄 상점 구매 등)은 거부해야 한다.
//  - 만료 시 재인증을 요구한다.
//
// 아래 코드에서 접속 시 인증과, 이후 요청 처리에서 권한을 확인하는 부분을 검토하라.
//
// 과제:
//  1) (A)(B) 를 중심으로, 장수명 연결에서 요구사항이 어떻게 깨지는지 설명하라.
//  2) 재현 시나리오를 제시하라.
//  3) 수정안을 제시하라.

using System;

public class Session
{
    public long AccountId;
    public bool Authenticated;
    public DateTime TokenExpiresAtUtc;
}

public class GameConnection
{
    private readonly Session _session = new Session();

    // 접속 직후 1회 호출
    public bool OnAuthenticate(AuthToken token)
    {
        if (!token.SignatureValid || token.ExpiresAtUtc <= DateTime.UtcNow)
            return false;

        // (A) 인증 성공 상태와 만료 시각을 세션에 저장
        _session.AccountId = token.AccountId;
        _session.Authenticated = true;
        _session.TokenExpiresAtUtc = token.ExpiresAtUtc;
        return true;
    }

    // 프리미엄 상점 구매 요청(세션 수명 동안 여러 번 도착)
    public void OnPremiumPurchase(int itemId)
    {
        // (B) 인증된 세션인지 확인 후 처리
        if (!_session.Authenticated)
        {
            Reject("not authenticated");
            return;
        }
        PremiumStore.Purchase(_session.AccountId, itemId);
    }

    private void Reject(string reason) { /* ... */ }
}

public struct AuthToken { public long AccountId; public bool SignatureValid; public DateTime ExpiresAtUtc; }
public static class PremiumStore { public static void Purchase(long acc, int item) { } }
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.