ASP.NET Core의 단순 권한 부여

ASP.NET Core의 권한 부여는 AuthorizeAttribute 및 해당하는 다양한 매개 변수를 사용하여 제어됩니다. 가장 기본적인 형태에서 컨트롤러, 작업 또는 Razor Page에 [Authorize] 특성을 적용하면 해당 구성 요소 인증 사용자에 대한 액세스를 제한합니다.

다음 코드는 AccountController에 대한 액세스를 인증된 사용자로 제한합니다.

[Authorize]
public class AccountController : Controller
{
    public ActionResult Login()
    {
    }

    public ActionResult Logout()
    {
    }
}

컨트롤러가 아닌 작업에 권한 부여를 적용하려면 작업 자체에 AuthorizeAttribute 특성을 적용합니다.

public class AccountController : Controller
{
   public ActionResult Login()
   {
   }

   [Authorize]
   public ActionResult Logout()
   {
   }
}

이제 인증된 사용자만 Logout 함수에 액세스할 수 있습니다.

또한 AllowAnonymous 특성을 사용하여 인증되지 않은 사용자의 개별 작업에 대한 액세스를 허용할 수 있습니다. 예시:

[Authorize]
public class AccountController : Controller
{
    [AllowAnonymous]
    public ActionResult Login()
    {
    }

    public ActionResult Logout()
    {
    }
}

이렇게 하면 인증된 사용자 또는 인증되지 않은 사용자/익명 상태에 관계없이 모든 사용자가 액세스할 수 있는 Login 작업을 제외하고 AccountController에 대해 인증된 사용자만 액세스할 수 있습니다.

Warning

[AllowAnonymous]는 권한 부여 문을 무시합니다. [AllowAnonymous][Authorize] 특성을 함께 사용할 경우 [Authorize] 특성이 무시됩니다. 예를 들어 컨트롤러 수준에서 [AllowAnonymous]을 적용하는 경우:

  • 컨트롤러의 동일한 컨트롤러 또는 작업 메서드에 있는 [Authorize] 특성의 권한 부여 요구 사항은 무시됩니다.
  • 인증 미들웨어는 단락되지 않지만 성공할 필요는 없습니다.

다음 코드는 LogoutModelRazor Page에 대한 액세스를 인증된 사용자로 제한합니다.

[Authorize]
public class LogoutModel : PageModel
{
    public async Task OnGetAsync()
    {

    }

    public async Task<IActionResult> OnPostAsync()
    {

    }
}

모든 사용자의 인증을 전역으로 요구하는 방법에 대한 자세한 내용은 인증된 사용자 요구를 참조하세요.

특성 및 Razor 페이지 권한 부여

AuthorizeAttribute는 Razor Page 처리기에 적용할 수 없습니다. 예를 들어 [Authorize]OnGet, OnPost 또는 다른 페이지 처리기에 적용할 수 없습니다. 다른 처리기에 대한 권한 부여 요구 사항이 서로 다른 페이지에는 ASP.NET Core MVC 컨트롤러를 사용하는 것이 좋습니다. 다른 권한 부여 요구 사항이 필요한 경우 MVC 컨트롤러를 사용하는 것은

  • 가장 덜 복잡한 방법입니다.
  • Microsoft에서 권장하는 방법입니다.

MVC 컨트롤러를 사용하지 않으려면 다음 두 가지 방법으로 Razor Page 처리기 메서드에 권한 부여를 적용할 수 있습니다.

  • 다른 권한 부여가 필요한 페이지 처리기에 대해 별도의 페이지를 사용합니다. 공유 콘텐츠를 하나 이상의 부분 보기로 이동합니다. 가능한 경우 이는 권장되는 방법입니다.

  • 공용 페이지를 공유해야 하는 콘텐츠의 경우 권한 부여를 IAsyncPageFilter.OnPageHandlerSelectionAsync의 일부로 수행하는 필터를 작성합니다. PageHandlerAuth GitHub 프로젝트는 이 방법을 설명합니다.

    • AuthorizeIndexPageHandlerFilter권한 부여 필터를 구현합니다.
    [TypeFilter(typeof(AuthorizeIndexPageHandlerFilter))]
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
    
        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }
    
        public void OnGet()
        {
    
        }
    
        public void OnPost()
        {
    
        }
    
        [AuthorizePageHandler]
        public void OnPostAuthorized()
        {
    
        }
    }
    
    public class AuthorizeIndexPageHandlerFilter : IAsyncPageFilter, IOrderedFilter
    {
        private readonly IAuthorizationPolicyProvider policyProvider;
        private readonly IPolicyEvaluator policyEvaluator;
    
        public AuthorizeIndexPageHandlerFilter(
            IAuthorizationPolicyProvider policyProvider,
            IPolicyEvaluator policyEvaluator)
        {
            this.policyProvider = policyProvider;
            this.policyEvaluator = policyEvaluator;
        }
    
        // Run late in the selection pipeline
        public int Order => 10000;
    
        public Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) => next();
    
        public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
        {
            var attribute = context.HandlerMethod?.MethodInfo?.GetCustomAttribute<AuthorizePageHandlerAttribute>();
            if (attribute is null)
            {
                return;
            }
    
            var policy = await AuthorizationPolicy.CombineAsync(policyProvider, new[] { attribute });
            if (policy is null)
            {
                return;
            }
    
            await AuthorizeAsync(context, policy);
        }
    
        #region AuthZ - do not change
        private async Task AuthorizeAsync(ActionContext actionContext, AuthorizationPolicy policy)
        {
            var httpContext = actionContext.HttpContext;
            var authenticateResult = await policyEvaluator.AuthenticateAsync(policy, httpContext);
            var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, httpContext, actionContext.ActionDescriptor);
            if (authorizeResult.Challenged)
            {
                if (policy.AuthenticationSchemes.Count > 0)
                {
                    foreach (var scheme in policy.AuthenticationSchemes)
                    {
                        await httpContext.ChallengeAsync(scheme);
                    }
                }
                else
                {
                    await httpContext.ChallengeAsync();
                }
    
                return;
            }
            else if (authorizeResult.Forbidden)
            {
                if (policy.AuthenticationSchemes.Count > 0)
                {
                    foreach (var scheme in policy.AuthenticationSchemes)
                    {
                        await httpContext.ForbidAsync(scheme);
                    }
                }
                else
                {
                    await httpContext.ForbidAsync();
                }
    
                return;
            }
        }
    

Warning

PageHandlerAuth 샘플 방법은 다음을 수행하지 않습니다.

  • 페이지, 페이지 모델 또는 전역적으로 적용되는 권한 부여 특성으로 구성합니다. 권한 부여 특성을 작성하면 하나 이상의 AuthorizeAttribute 또는 AuthorizeFilter 인스턴스가 페이지에도 적용될 때 인증 및 권한 부여가 여러 번 실행됩니다.
  • ASP.NET Core 인증 및 권한 부여 시스템의 나머지 부분과 함께 작업합니다. 이 접근 방식을 사용할 때 애플리케이션에서 제대로 작동하는지 확인해야 합니다.

Razor Page 처리기에서 AuthorizeAttribute를 지원할 계획이 없습니다.