ASP .NET Core 3.1 - Usando o Identity de cabo a rabo - VIII


Hoje vamos continuar a série de artigos mostrando como usar o ASP .NET Core Identiy na versão 3.1 da ASP .NET .Core e do EF Core.

Continuando a sétima parte do artigo veremos oque é e como usar a autorização em nosso projeto.

O que é a autorização ou Authorization na ASP .NET Core ?

A autenticação ou Authentication é o processo de identificar que o usuário é.

Já a autorização ou Authorization é o processo de identificar oque o usuário pode e não pode fazer.

Assim se o usuário logado for um Administrador ele poderá criar, ler, atualizar e deletar informações. Já um usuário nomal poderá somente visualizar informações e não poderá realizar as demais tarefas.

Na ASP .NET Core a autorização é controlada através da classe AuthorizeAttribute que especifica que a classe ou método no qual este atributo for aplicado vai requerer uma autorização específica dependendo dos parâmetros usados.

Percebeu que mesmo fazendo o registro e o login de um usuário qualquer usuário anônimo consegue acessar a nossa aplicação e realizar todas as operações.

É para isso que usamos o atributo [Authorize], pois na sua forma mais simples, sem parâmetros, ele apenas vai verificar se o usuário esta autenticado.

Então, podemos usar o atributo [Authorize] na classe FuncionariosController, e assim, ele será aplicado a todos os métodos Action, e vai atuar verificando se o usuário esta logado ou não, e com base nisso vai permitir o acesso a cada método Action :

   [Authorize]
    public class FuncionariosController : Controller
    {
        ...
        public async Task<IActionResult> Index()
        {
        }
        ...
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
        }
        private bool FuncionarioExists(int id)
        {
        }
    }

Agora para acessar qualquer método do controlador FuncionariosController temos que estar autenticado.

Para usar o atributo [Authorize] precisamos referenciar o namespace Microsoft.AspNetCore.Authorization;

Além disso podemos aplicar o atributo [Authorize] em métodos individuais, e, neste caso ele somente vai atuar neste método.

No exemplo abaixo temos o atributo aplicado somente ao método Create(), e,  neste caso somente este método vai exigir que o usuário esteja autenticado:

    public class FuncionariosController : Controller
    {
        ...
        public async Task<IActionResult> Details(int? id)
        {
        }
        [Authorize]
        public IActionResult Create()
        {
        }
        .....        
        private bool FuncionarioExists(int id)
        {
        }
    }

Além deste atributo existe também o atributo AllowAnonymousAttribute que garante o acesso anônimo ao método ou classe no qual for aplicado. Em geral usamos esse atributo em combinação com o atributo Authorize.

Assim podemos aplicar o atributo Authorize na classe do controlador e todos os seus métodos estarão protegidos. Mas se quisermos que um destes métodos permita o acesso anônimo podemos usar o atributo [AllowAnonymous].

No exemplo a seguir aplicamos o atributo [Authorize] a nível de controlador e o atributo [AllowAnonymous] ao método Action Details:

    [Authorize]
    public class FuncionariosController : Controller
    {
        ...
        [AllowAnonymous]
        public async Task<IActionResult> Details(int? id)
        {
        }
        .....        
        private bool FuncionarioExists(int id)
        {
        }
    }

Assim somente o método Details vai permitir o acesso de um usuário não autenticado.

Nota: Se você aplicar o atributo [AllowAnonymous] a nível de controlador vai permitir o acesso anônimo a qualquer método (o que já é o padrão) mesmo se usar o atributo [Authorize] nos métodos Action.

Aplicando o atributo Authorize globalmente

Podemos aplicar o atributo [Authorize] globalmente em todos os controladores e métodos Action do controlador no aplicativo.

Para isso basta modificar o código no método ConfigureServices da classe Startup conforme a seguir:

       public void ConfigureServices(IServiceCollection services)
       {
             ...
            services.AddControllersWithViews(config=>
            {
                var policy = new AuthorizationPolicyBuilder()
                       .RequireAuthenticatedUser()
                       .Build();
                config.Filters.Add(new AuthorizeFilter(policy));
            });
        }

Este código vai exigir a utilização dos namespaces :

Agora para poder ter acesso a nossa aplicação teremos que aplicar o atributo [AllowAnonymous] pelo menos no método Login do controlador AccountController.

Se isso não for feito iremos obter a seguinte mensagem de erro:

HTTP Error 404.15 - Not Found

The request filtering module is configured to deny a request where the query string is too long.

Most likely causes:
Request filtering is configured on the Web server to deny the request because the query string is too long.

 

Vamos entender porque isso esta ocorrendo:

  1. Para acessar a aplicação você será direcionando para /Account/login;
  2. Como o atributo [Authorize] esta sendo aplicado globalmente, não poderemos acessar o método /Account/Login para fazer o login;
  3. Entramos então em um laço infinito e a cada redirecionamento a string ?ReturnUrl=/Account/Login será anexada à URL
  4. Então teremos o erro : Web Server denied the request because the query string is too long.


Para resolver esse erro, basta aplicar o atributo [AllowAnonymous] aos métodos Login do controlador AccountController.

Ao acessar nossa aplicação seremos direcionados para a página de Login e após o login poderemos acessar a aplicação.

No próximo artigo veremos redirecionar o usuário para a URL solicitada após o login bem sucedido e como prevenir do ataque de redirecionamento aberto.

Pegue o código do projeto aqui :  IdentityTotal_Authorize.zip  (sem as referências)

"O temor do Senhor é fonte de vida, para desviar dos laços da morte."
Provérbios 14:26,27

Referências:


José Carlos Macoratti