A sua sessão expirou

by Israel Aece 28. July 2009 08:18

Um amigo me pediu uma ajuda para escrever a seguinte mensagem na página de Login de uma aplicação ASP.NET: "A sua sessão expirou. Efetue o login novamente.". Como ele está utilizando FormsAuthentication, pensei em analisar a existência da QueryString "ReturnUrl", que geralmente é adicionada como parte da URL, quando você tenta acessar algum recurso protegido e que você não esteja devidamente autenticado.

O problema desta técnica é que as vezes o usuário tem o endereço (nos "Favoritos", por exemplo) desta página restrita, e suponhamos que ele abra o navegador e tente acessá-la diretamente. O FormsAuthentication fará a parte dele, ou seja, redirecionará o usuário para a página de Login com a QueryString "ReturnUrl" contendo a página que ele tentou acessar. Se estiver analisando essa QueryString, a mensagem de "sessão expirada" será exibida, mas não faz sentido neste caso, já que é o primeiro acesso deste usuário.

Para tentar contornar esse problema, a solução foi a criação de um módulo, vinculando ao evento BeginRequest. Esse módulo será responsável por analisar a validade do cookie de autenticação, e se estiver expirado, redirecionará o usuário para a página de Login. Esse mesmo processo acaba sendo feito pelo próprio FormsAuthenticationModule, mas com este novo módulo, a ideia é nos antecipar ao FormsAuthentication e adicionar um novo item na coleção de QueryStrings, que especifica que a autenticação expirou. Esse valor será analisado pela página de Login, que baseando-se nele irá ou não exibir a mensagem em questão. Abaixo temos o módulo na íntegra:

using System;
using System.Web;
using System.Web.Security;

public class AuthenticationExpiredModule : IHttpModule
{
    private HttpApplication _app;

    public void Init(HttpApplication context)
    {
        this._app = context;
        this._app.BeginRequest += new EventHandler(this._app_BeginRequest);
    }

    private void _app_BeginRequest(object sender, EventArgs e)
    {
        if (this._app.Request.Path != FormsAuthentication.LoginUrl)
        {
            HttpCookie authCookie = 
                this._app.Request.Cookies[FormsAuthentication.FormsCookieName];

            if (authCookie != null)
            {
                FormsAuthenticationTicket ticket =
                    FormsAuthentication.Decrypt(authCookie.Value);

                if (ticket.Expired)
                {
                    this._app.CompleteRequest();
                    FormsAuthentication.RedirectToLoginPage("Authentication=Expired");
                }
            }
        }
    }

    public void Dispose() { }
}

Depois de criado, precisamos registrá-lo no arquivo de configuração (Web.config) para que ele comece a fazer parte da execução:

<httpModules>
    <add
        name="AuthenticationExpiredModule"
        type="AuthenticationExpiredModule"/>
</httpModules>

E, finalmente, já na página de Login, verificando a existência da QueryString:

this.AuthenticationExpiredMessage.Visible = Request.QueryString["Authentication"] == "Expired";

Tags: ,

ASP.NET | Security

Comments

9/22/2009 11:57:27 PM #

João Paulo Marson

olá Israel, muito boa a solução.
Como faço a mesma coisa só que em asp usando vb.net?

Se puder me mandar um exemplo eu agradeço.



Obrigado e um abaraço!

João Paulo Marson Brazil

9/23/2009 8:15:53 AM #

IsraelAece

Boas João,

Você se refere a ASP.NET com VB.NET?

Se sim, você pode utilizar um tradutor para isso: http://www.carlosag.net/Tools/CodeTranslator/

IsraelAece Brazil

6/22/2010 10:33:59 AM #

Everaldo

Israel,

Para vs2003 isso funciona?
Precisa fazer alguma alteração?
Erro no if: If (Me._app.Request.Path <> FormsAuthentication.LoginUrl) Then
e no: FormsAuthentication.RedirectToLoginPage("Authentication=Expired", False)

Obrigado,

Everaldo Brazil

6/22/2010 10:39:05 AM #

IsraelAece

Boas Everaldo,

Em princípio deveria funcionar. Qual a mensagem exata do erro?

IsraelAece Brazil

9/30/2010 11:40:17 AM #

Vanessa Nunes

Bom dia, tentei traduzir para o VB.NET mas nao funcionou.
Ele nao encontra o IHttpModule etc etc.

Obrigada

Vanessa Nunes Brazil

9/30/2010 11:43:31 AM #

IsraelAece

Boas Vanessa,

Você precisa fazer a referência para o assembly System.Web.dll e importar o namespace com o mesmo nome.

IsraelAece Brazil

10/1/2010 5:11:09 PM #

Renato Godoi

Olá Israel,
Valeu pelo post, achei muito interessante e de grande valia, porém, não consegui utilizá-lo pois quando eu altero no web.config o <httpmodules> mais precisamente quando eu limpo com o comando <clear/> o controle de acesso que tinha no website, através do MembershipProvider, para de funcionar.
Você faz ideia porque isso ocorre?

Att,

Renato Godoi Brazil

10/4/2010 8:17:25 AM #

IsraelAece

Boas Renato,

O problema é que dando o <clear /> você está removendo o FormsAuthenticationModule, que é necessário para o FormsAuthentication funcionar.

IsraelAece Brazil

Comments are closed

Powered by BlogEngine.NET 1.5.0.0
Theme by Mads Kristensen

Sobre

Meu nome é Israel Aece e sou especialista em tecnologias de desenvolvimento Microsoft, atuando como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. [ Mais ]

Twitter

Host