Jednoduchá autorizace v ASP.NET Core

Autorizace v ASP.NET Core se řídí atributem [Authorize] a jeho různými parametry. Ve své nejzákladnější podobě omezuje použití atributu [Authorize] na kontroler, akci nebo Razor stránku přístup k této komponentě ověřeným uživatelům.

Požadavky

Tento článek předpokládá, že máte základní znalosti o ASP.NET základních Razor stránek a MVC. Pokud s ASP.NET Core začínáte, projděte si následující zdroje informací:

Použití atributu [Authorize]

Následující kód omezuje přístup k AccountController ověřeným uživatelům:

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

    public ActionResult Logout()
    {
    }
}

Pokud chcete místo kontroleru použít autorizaci na akci, použijte AuthorizeAttribute atribut na samotnou akci:

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

   [Authorize]
   public ActionResult Logout()
   {
   }
}

Teď k Logout funkci mají přístup jenom ověření uživatelé.

Pomocí atributu AllowAnonymous můžete také povolit přístup neověřené uživatele k jednotlivým akcím. Příklad:

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

    public ActionResult Logout()
    {
    }
}

To by umožnilo pouze ověřeným uživatelům AccountController, s výjimkou Login akce, která je přístupná všemi, bez ohledu na jejich ověřený nebo neověřený / anonymní stav.

Upozorňující

[AllowAnonymous] obchází autorizační příkazy. Pokud zkombinujete [AllowAnonymous] atribut a [Authorize] atribut, [Authorize] budou atributy ignorovány. Pokud například použijete [AllowAnonymous] úroveň kontroleru:

  • Všechny požadavky na autorizaci z [Authorize] atributů na stejném kontroleru nebo metodách akcí na kontroleru se ignorují.
  • Middleware pro ověřování není zkrácený, ale nemusí být úspěšný.

Následující kód omezuje přístup ke LogoutModelRazor stránce ověřeným uživatelům:

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

    }

    public async Task<IActionResult> OnPostAsync()
    {

    }
}

Informace o tom, jak globálně vyžadovat ověření všech uživatelů, najdete v tématu Vyžadování ověřených uživatelů.

Autorizace atributu a Razor stránek

U AuthorizeAttribute obslužných rutin stránky nelze použítRazor. [Authorize] Například nelze použít pro OnGet, OnPostani pro žádnou jinou obslužnou rutinu stránky. Zvažte použití kontroleru ASP.NET Core MVC pro stránky s různými požadavky na autorizaci pro různé obslužné rutiny. Použití kontroleru MVC v případě, že jsou vyžadovány různé požadavky na autorizaci:

  • Je nejsložitější přístup.
  • Doporučuje microsoft.

Pokud se rozhodnete, že nebudete používat kontroler MVC, můžete použít následující dva přístupy k použití autorizace na Razor metody obslužné rutiny stránky:

  • Pro obslužné rutiny stránek, které vyžadují jinou autorizaci, použijte samostatné stránky. Přesuňte sdílený obsah do jednoho nebo více částečných zobrazení. Pokud je to možné, doporučuje se to.

  • Pro obsah, který musí sdílet společnou stránku, napište filtr, který provádí autorizaci jako součást IAsyncPageFilter.OnPageHandlerSelectionAsync. Projekt PageHandlerAuth Na GitHubu ukazuje tento přístup:

    • AuthorizeIndexPageHandlerFilter implementuje autorizační filtr:
    [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;
            }
        }
    

Upozorňující

Ukázkový přístup PageHandlerAuth:

  • Psaní s autorizačními atributy použitými na stránku, model stránky nebo globálně Výsledkem vytváření atributů autorizace je vícenásobné provádění ověřování a autorizace, pokud máte na stránce také použitou jednu AuthorizeAttribute instanci AuthorizeFilter .
  • Spolupracujte ve spojení se zbytkem ASP.NET základního systému ověřování a autorizace. Musíte ověřit, že tento přístup funguje správně pro vaši aplikaci.

Na obslužných rutinách stránky se neplánují podporovat AuthorizeAttributeRazor .