ASP.NET Core에서 커스텀 인증 및 권한 부여 이해하기

1. 인증의 개념과 원리

인증은 요청자가 누구인지 확인하는 과정입니다. 이는 단순히 사용자 식별을 넘어서, 시스템이 그 사용자의 신원을 신뢰할 수 있도록 하는 절차입니다.

예를 들어, 특정 건물에 접근하려는 사용자는 보안 요원(인증 처리기)에게 자신의 신원을 제시해야 합니다. 만약 사용자가 정식 초대장(접근 토큰)을 가지고 있다면, 보안 요원은 이를 검증하고 사용자를 인식합니다. 이때 생성되는 정보가 AuthenticationTicket이며, 이는 사용자의 정체성과 권한을 포함합니다.

반대로, 토큰이 없거나 유효하지 않으면 인증 실패로 처리되며, 이는 NoResult 또는 Fail 상태로 반환됩니다.

2. 인증과 로그인의 차이

로그인은 인증의 한 가지 형태일 뿐입니다. 즉, 로그인 요청 자체도 인증 프로세스를 거쳐야 하며, 이 과정에서 인증 처리기가 작동합니다.

예를 들어, 관리자에게 직접 전화를 걸어 초대장을 받는 행위는 로그인 과정이며, 이 과정에서도 인증(초대장의 유효성 검사)과 권한(관리자 승인 여부)이 적용됩니다. 이처럼 로그인도 일반적인 요청과 마찬가지로 인증 및 권한 검사를 수행합니다.

3. 커스텀 인증 처리기 구현

ASP.NET Core 7 기준으로, 커스텀 인증 메커니즘은 IAuthenticationHandler를 상속하여 구현할 수 있습니다. 다음은 간단한 토큰 기반 인증 처리기 예제입니다.

using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using System.Text.Encodings.Web;

namespace WebApplication1.Authentication
{
    public class CustomAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
    {
        public CustomAuthHandler(
            IOptionsMonitor<AuthenticationSchemeOptions> options,
            ILoggerFactory logger,
            UrlEncoder encoder,
            ISystemClock clock)
            : base(options, logger, encoder, clock)
        { }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            var token = Request.Headers["auth-token"].ToString();

            if (string.IsNullOrEmpty(token))
                return AuthenticateResult.NoResult();

            if (token == "secure_token_2024")
            {
                var identity = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Role, "Teacher"),
                    new Claim(ClaimTypes.Name, "김선생")
                }, "CustomAuth");

                var principal = new ClaimsPrincipal(identity);
                var ticket = new AuthenticationTicket(principal, "CustomAuth");

                return AuthenticateResult.Success(ticket);
            }

            return AuthenticateResult.Fail(new Exception("유효하지 않은 토큰"));
        }

        protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
        {
            await base.HandleChallengeAsync(properties);
        }

        protected override Task HandleForbiddenAsync(AuthenticationProperties properties)
        {
            return base.HandleForbiddenAsync(properties);
        }
    }
}

4. 권한 부여 정책 설정

권한 부여는 인증된 사용자가 특정 리소스에 접근할 수 있는지를 결정합니다. AuthorizeAttribute를 통해 다양한 정책을 적용할 수 있습니다.

예를 들어, Admin 또는 Teacher 역할을 가진 사용자만 접근 가능하도록 정책을 추가합니다.

// Program.cs
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AccessRestricted", policy =>
    {
        policy.RequireRole("Admin", "Teacher");
    });
});

이 정책을 컨트롤러나 액션에 적용하면, 해당 엔드포인트는 지정된 역할을 가진 사용자만 접근 가능하게 됩니다.

[ApiController]
[Route("[controller]")]
public class DataController : ControllerBase
{
    [Authorize(Policy = "AccessRestricted")]
    public IActionResult GetData()
    {
        return Ok(new { message = "접근 성공" });
    }
}

5. 특수 경우: 비인증 접근 허용

특정 액션은 인증되지 않은 사용자도 접근할 수 있도록 하기 위해 [AllowAnonymous] 어트리뷰트를 사용할 수 있습니다.

[Authorize]
public class AccountController : Controller
{
    [AllowAnonymous]
    public IActionResult SignIn() => View();

    public IActionResult SignOut() => RedirectToAction("SignIn");
}

태그: ASP.NET Core 인증 권한 부여 Claims AuthenticationHandler

7월 15일 04:52에 게시됨