none
Sincronia entre FormsAuthentication e Session RRS feed

  • Pergunta

  • Pessoal,

    Há algum tempo tenho alguns "probleminhas" em manter "sincronizado" a autenticação do FormsAuthentication com a Session do usuário.

    Em vários casos eu preciso manter informação sensível do usuário na sessão dele, enquanto estiver logado. Ou seja, quando o usuário se loga na aplicação (usando o FormsAuthentication) eu armazeno algumas informações (apenas o que for necessário) na sessão do mesmo.

    Antes que alguém pense que pode ser armazenado no cookie que é gravado pelo Forms, eu adianto que isso não é possível, pelo contexto que eu estou utilizando.

    O problema, na realidade, ocorre na expiração da Session. Quando esta expira, não necessariamente a autenticação do Forms também. Assim o usuário fica logado na aplicação (via Forms), mas sem as informações necessárias que estão na Session.

    Eu tinha criado uma alternativa, que presumi funcionar e acabei esquecendo de certificar disso. Quando realmente percebi, o WebSite já estava em produção (shit happens)!!!

    O que fiz foi forçar, através do Global.asax, a saida do usuário, conforme segue:

    Code Snippet

    protected void Session_End(Object sender, EventArgs e)
    {
       FormsAuthentication.SignOut();
    }


    Como citei, por alguma cargas d'água (não entrei no mérito do por que) não funciona.

    Criei uma opção alternativa (POG++) que prefiro nem colocar por aqui.

    Mas, essa semana, numa dessas noites que vocês sonha com soluções estranhas para problemas estranhos, pensei na seguinte saída: Verificar, ainda no Global.asax, se a sessão do usuário existe. Caso não ele força saída do Forms, conforme segue:

    Code Snippet

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
       if(Session["MyVar"] == null)
       {
          FormsAuthentication.SignOut();
       }
    }


    De fato, eu preciso muito manter a sincronia entre esses dois camaradas. Ainda não tive o problema inverso, ou seja, a autenticação do Forms encerrar e a sessão ficar. Mesmo que fique, isso não é problema, pois o usuário, para acessar qualquer das páginas restritas (e que por sua vez utilizam dados da session), terá que se logar novamente.

    Alguém tem alguma solução, que não seja POG, para isso? Ou o Fw.Net permite, de alguma forma, manter a sincronia de "vida" entre esses dois?

    Valeu!!!
    sexta-feira, 26 de setembro de 2008 17:45

Respostas

  • Alô meu povo!

    Depois de tanto tempo sem resposta e de várias tentativas frustradas, consegui fuçando diversos lugares uma possível solução.
    Fiz diversos testes, exceto performance, e me atendeu 100%.

    O código abaixo deve ser colocado no Global.asax.


            protected void Application_AcquireRequestState(object sender, EventArgs e) 
            { 
                HttpSessionState session = ((HttpApplication)sender).Context.Session; 
     
                if (session != null && session.IsNewSession) 
                { 
                    if (User.Identity.IsAuthenticated) 
                    { 
                        FormsAuthentication.SignOut(); 
                        FormsAuthentication.RedirectToLoginPage(); 
                    } 
                } 
            } 

    Só uma dúvida ainda me persegue. Esse método é chamado diversas vezes, durante a requisição de uma mesma página.
    Quais as situações em que ele é executado.

    A verificação de session == null eu tive que fazer, pois das várias chamadas que são feitas a este método durante um request, apenas a primeira retorna diferente de null.

    Espero que isso seja de valia para muitos...
    Se alguém tiver alguma solução melhor ou qualquer sugestão, manda bala!!!

    Abraços,

    Danilo Freitas - Se resolveu, classifique a mensagem, por favor!
    • Marcado como Resposta Danilo Freitas domingo, 22 de março de 2009 04:04
    domingo, 22 de março de 2009 04:02
  • Um pequeno ajuste:

    Ao invés de redirecionar para a página de login, o mesmo deve ser feito para a mesma página. Da forma que está, até mesmo as páginas que não são restriras há o redirecionamento para a página de login.

    Com a alteração abaixo, haverá o redirecionamento para a mesma página e a sessão e o token de autenticação (se existir) será recriado sem redirecionar para a página de login (somente ocorrerá se a página corrente for de acesso restrito).

            protected void Application_AcquireRequestState(object sender, EventArgs e)
            {
                HttpSessionState session = ((HttpApplication)sender).Context.Session;

                if (session != null && session.IsNewSession)
                {
                    if (User.Identity.IsAuthenticated)
                    {
                        FormsAuthentication.SignOut();
                        HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl);
                    }
                }
            }


    Mamão com açúcar! Se resolveu, classifique a mensagem, por favor!
    • Marcado como Resposta Danilo Freitas segunda-feira, 26 de abril de 2010 17:00
    segunda-feira, 26 de abril de 2010 17:00

Todas as Respostas

  • Alô meu povo!

    Depois de tanto tempo sem resposta e de várias tentativas frustradas, consegui fuçando diversos lugares uma possível solução.
    Fiz diversos testes, exceto performance, e me atendeu 100%.

    O código abaixo deve ser colocado no Global.asax.


            protected void Application_AcquireRequestState(object sender, EventArgs e) 
            { 
                HttpSessionState session = ((HttpApplication)sender).Context.Session; 
     
                if (session != null && session.IsNewSession) 
                { 
                    if (User.Identity.IsAuthenticated) 
                    { 
                        FormsAuthentication.SignOut(); 
                        FormsAuthentication.RedirectToLoginPage(); 
                    } 
                } 
            } 

    Só uma dúvida ainda me persegue. Esse método é chamado diversas vezes, durante a requisição de uma mesma página.
    Quais as situações em que ele é executado.

    A verificação de session == null eu tive que fazer, pois das várias chamadas que são feitas a este método durante um request, apenas a primeira retorna diferente de null.

    Espero que isso seja de valia para muitos...
    Se alguém tiver alguma solução melhor ou qualquer sugestão, manda bala!!!

    Abraços,

    Danilo Freitas - Se resolveu, classifique a mensagem, por favor!
    • Marcado como Resposta Danilo Freitas domingo, 22 de março de 2009 04:04
    domingo, 22 de março de 2009 04:02
  • Um pequeno ajuste:

    Ao invés de redirecionar para a página de login, o mesmo deve ser feito para a mesma página. Da forma que está, até mesmo as páginas que não são restriras há o redirecionamento para a página de login.

    Com a alteração abaixo, haverá o redirecionamento para a mesma página e a sessão e o token de autenticação (se existir) será recriado sem redirecionar para a página de login (somente ocorrerá se a página corrente for de acesso restrito).

            protected void Application_AcquireRequestState(object sender, EventArgs e)
            {
                HttpSessionState session = ((HttpApplication)sender).Context.Session;

                if (session != null && session.IsNewSession)
                {
                    if (User.Identity.IsAuthenticated)
                    {
                        FormsAuthentication.SignOut();
                        HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl);
                    }
                }
            }


    Mamão com açúcar! Se resolveu, classifique a mensagem, por favor!
    • Marcado como Resposta Danilo Freitas segunda-feira, 26 de abril de 2010 17:00
    segunda-feira, 26 de abril de 2010 17:00