Partilhar via


Autorização simples no ASP.NET Core

A autorização no ASP.NET Core é controlada com o [Authorize] atributo e seus vários parâmetros. Em sua forma mais básica, a aplicação do atributo a um controlador, ação ou [Authorize] Página limita o Razor acesso a esse componente a usuários autenticados.

Pré-requisitos

Este artigo pressupõe que você tenha uma compreensão básica de ASP.NET Core Razor Pages e MVC. Se você é novo no ASP.NET Core, consulte os seguintes recursos:

Use o [Authorize] atributo

O código a seguir limita o AccountController acesso aos usuários autenticados:

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

    public ActionResult Logout()
    {
    }
}

Se você quiser aplicar autorização a uma ação em vez do controlador, aplique o AuthorizeAttribute atributo à ação em si:

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

   [Authorize]
   public ActionResult Logout()
   {
   }
}

Agora, apenas usuários autenticados podem acessar a Logout função.

Você também pode usar o atributo para permitir o AllowAnonymous acesso de usuários não autenticados a ações individuais. Por exemplo:

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

    public ActionResult Logout()
    {
    }
}

Isso permitiria apenas usuários autenticados para o AccountController, exceto para a Login ação, que é acessível por todos, independentemente de seu status autenticado ou não autenticado / anônimo.

Advertência

[AllowAnonymous] ignora as declarações de autorização. Se você combinar [AllowAnonymous] e um [Authorize] atributo, os [Authorize] atributos serão ignorados. Por exemplo, se você se inscrever [AllowAnonymous] no nível do controlador:

  • Quaisquer requisitos de autorização de atributos no mesmo controlador ou métodos de [Authorize] ação no controlador são ignorados.
  • O middleware de autenticação não está em curto-circuito, mas não precisa ser bem-sucedido.

O código a seguir limita o acesso à LogoutModelRazor Página a usuários autenticados:

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

    }

    public async Task<IActionResult> OnPostAsync()
    {

    }
}

Para obter informações sobre como exigir globalmente que todos os usuários sejam autenticados, consulte Exigir usuários autenticados.

Autorizar atributo e Razor Páginas

O AuthorizeAttributenão pode ser aplicado a Razor manipuladores de página. Por exemplo, [Authorize] não pode ser aplicado ao OnGet, OnPostou a qualquer outro manipulador de página. Considere o uso de um controlador MVC ASP.NET Core para páginas com requisitos de autorização diferentes para manipuladores diferentes. Usando um controlador MVC quando diferentes requisitos de autorização são necessários:

  • É a abordagem menos complexa.
  • É a abordagem recomendada pela Microsoft.

Se você decidir não usar um controlador MVC, as duas abordagens a seguir podem ser usadas para aplicar autorização aos Razor métodos do manipulador de página:

  • Use páginas separadas para manipuladores de página que exigem autorização diferente. Mova o conteúdo compartilhado para uma ou mais visualizações parciais. Sempre que possível, esta é a abordagem recomendada.

  • Para conteúdo que deve compartilhar uma página comum, escreva um filtro que execute a autorização como parte de IAsyncPageFilter.OnPageHandlerSelectionAsync. O projeto PageHandlerAuth GitHub demonstra essa abordagem:

    [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;
            }
        }
    

Advertência

A abordagem de exemplo PageHandlerAuthnão:

  • Componha com atributos de autorização aplicados à página, modelo de página ou globalmente. A composição de atributos de autorização resulta na execução de autenticação e autorização várias vezes quando você tem mais AuthorizeAttribute uma ou AuthorizeFilter instâncias também aplicadas à página.
  • Trabalhe em conjunto com o resto do ASP.NET sistema de autenticação e autorização Core. Você deve verificar se o uso dessa abordagem funciona corretamente para seu aplicativo.

Não há planos para dar suporte aos AuthorizeAttribute manipuladores na Razor página.