Página de Acesso Negado


Quando utilizamos FormsAuthentication para proteger uma determina página ou diretório, há um comportamento que talvez não agrade a maioria das pessoas. Suponhamos que você faça o login digitando o seu nome de usuário e senha. Ao validar esse usuário em algum repositório, o ASP.NET automaticamente redireciona o usuário para a página/diretório que ele tentou acessar inicialmente.

A partir daí, se você utilizar roles para restringir o acesso à alguma página/diretório dentro da aplicação e o usuário não esteja dentro dela, ele será redirecionado – novamente – para a página de login. Talvez isso não seja o ideal, já que o mais coerente seria redirecionar o usuário para uma página que contenha uma mensagem mais amigável e próxima ao que realmente aconteceu, algo como: “Você não tem permissão para acessar o recurso solicitado. Contate o Administrator.”.

Quando utilizamos a UrlAuthorization (que já é o padrão), a cada requisição ela verifica se o usuário que acessa uma determinada página, possui a permissão para isso. Caso a configuração no arquivo Web.config diz que, para acessar aquela página, é necessário que o usuário esteja na role de “Administradores”, e ele por sua vez não estiver, o UrlAuthorization define a propriedade StatusCode da resposta do HTTP para 401 (que significa “Acesso Negado”). O FormsAuthentication (mais precisamente, o FormsAuthenticationModule) se vincula ao evento EndRequest, e dentro dele analisa se a propriedade StatusCode foi definida como 401. Caso tenha sido, o FormsAuthenticationModule redireciona o usuário para a página de login, trocando o StatusCode para 302 (“Redirecionar”).

Para mudar este comportamento, podemos criar um módulo e nos vincularmos ao evento EndRequest. Dentro deste evento, podemos analisar se a propriedade StatusCode foi definida como 401, e se estiver, redirecionar para uma página que informa exibe a mensagem correta ao invés da página de login, melhorando assim a navegabilidade da aplicação. O módulo é extremamente simples, assim como podemos notar abaixo:

public class AccessDeniedModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.EndRequest += new EventHandler(context_EndRequest);
    }

    private void context_EndRequest(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (app.Response.StatusCode == 401 && app.User.Identity.IsAuthenticated)
        {
            app.Response.Redirect(“~/AreaRestrita/AcessoNegado.aspx”);
        }
    }

    public void Dispose() { }
}

Como já sabemos, para que um módulo funcione, precisamos acoplá-lo na execução do ASP.NET, e fazemos isso através do elemento <httpModules />. Mas este módulo deve ter um cuidado especial para que funcione adequadamente. Já existem diversos módulos em execução pelo ASP.NET, e um deles é justamente o FormsAuthenticationModule. Se simplesmente adicionarmos o módulo que criamos na coleção de módulos da aplicação, o StatusCode vai chegar sempre como 302, pois a requisição primeiramente passará pelo módulo FormsAuthenticationModule, que como vimos acima, faz essa mudança. Com isso, a nossa condicional sempre irá falhar, fazendo com que o usuário seja redirecionado para a página de login. A dica aqui é ir até o arquivo Web.config que está em nível de servidor (%windir%Microsoft .NETFrameworkVERSÃOCONFIG), copiar a coleção de módulos e colar no arquivo Web.config da aplicação, como podemos ver abaixo:

<httpModules>
  <clear />
  <add name=”ScriptModule”
       type=”System.Web.Handlers.ScriptModule, System.Web.Extensions”/>
  <add name=”OutputCache”
       type=”System.Web.Caching.OutputCacheModule”/>
  <add name=”Session”
       type=”System.Web.SessionState.SessionStateModule”/>
  <add name=”AccessDeniedModule”
       type=”AccessDeniedModule”/>

  <add name=”FormsAuthentication”
       type=”System.Web.Security.FormsAuthenticationModule”/>
  <add name=”RoleManager”
       type=”System.Web.Security.RoleManagerModule”/>
  <add name=”UrlAuthorization”
       type=”System.Web.Security.UrlAuthorizationModule”/>
  <add name=”AnonymousIdentification”
       type=”System.Web.Security.AnonymousIdentificationModule”/>
  <add name=”Profile”
       type=”System.Web.Profile.ProfileModule”/>
</httpModules>

Depois de colocar os módulos no arquivo Web.config da aplicação, precisamos colocar o elemento <clear /> para que não duplique a execução dos módulos. E para finalizar, o módulo que criamos deverá ser colocado antes do módulo do FormsAuthentication para que funcione como o esperado. Aproveitando a oportunidade, é importante que você deixe somente os módulos que a sua aplicação realmente utiliza, ganhando alguma performance, já que evitará passar por passos desnecessários. Para maiores detalhes sobre isso, consulte este artigo.

Publicidade

7 comentários sobre “Página de Acesso Negado

    • Boas Fabio,

      Apesar de isso funcionar, não é uma forma elegante. Com a técnica que você sugere, o processo acontece da seguinte forma:

      PaginaRestrita.aspx (401) -> Login.aspx (302) -> NotAuthorized.aspx (302)

      No exemplo que fiz:

      PaginaRestrita.aspx (401) -> NotAuthorized.aspx (302)

      Além disso, código de infraestrutura não deve estar "jogado" pela aplicação. Utilizar módulos como foi o caso aqui, fica muito mais simples para gerenciar e, principalmente, para reutilizar em diversas outras aplicações.

    • Israel boa tarde,
      Existe algum forma de bloquear o acesso a pasta /admin/default.aspx ? tipo tem um site com gerenciador e queria liberar o acesso a essa pasta só para algumas pessoas pq se deixar aberto fico com medo de os hackers tentar colocar um robô para derrubar o servidor ou descobrir até a senha. existe alguma maneira ?

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s