2012-01-24 10 views
15

Używam FormsAuthentication, mam problemy z ustawieniem wartości TimeOut.Limit czasu nie działa w ASP.Net MVC FormsAuthentication

Widziałem kilka innych postów związanych z tym, ale nie wydają mi się one dokładnie moim problemem lub sugerowane rozwiązanie nie pomaga.

Moje web.config ma następujący:

<authentication mode="Forms"> 
    <forms loginUrl="~/Account/LogOn" 
     timeout="1" 
     cookieless="UseCookies" /> 
</authentication> 

mam położyć AuthorizeAttribute na kontrolerach, które chcę zabezpieczyć.

Mogę wyświetlić plik cookie .ASPXAUTH (przy użyciu FireCookies) i widzę, że wygasa w 1 minutę po zalogowaniu.

Jeśli debugować za pośrednictwem mojego kodu widzę, że FormsAuthentication.Timeout = 1.

Jednak mój bilet nie wydaje się limit czasu w ciągu 1 minuty. Po 1 minucie bezczynności nadal mogę przeglądać kontrolery za pomocą AuthorizeAttribute.

W rzeczywistości mogę faktycznie usunąć plik cookie .ASPXAUTH za pomocą FireCookies i nadal mogę przeglądać kontrolery z atrybutem AuthorizeAttribute.

Dziwacznie po byciu nieaktywnym przez długi czas (przepraszam, nie mam dokładnego czasu - byłem na lunch!) Pojawia się TimeOut i jestem przekierowywany na ekran logowania.

Wszelkie pomysły?

Odpowiedz

0

Chodzi o to, jak długi jest limit czasu sesji. Domyślnie jest to 20 minut i można ją zmienić w pliku web.config tak:

<sessionState mode="InProc" timeout="20"/> 
+2

Jednak stan sesji jest oddzielony od pliku cookie AuthenticationTicket/.ASPXAUTH. Przynajmniej tak myślę ?! – bplus

+0

jeśli nie używasz plików cookie do przechowywania tych danych, to sesja jest odpowiedzialna za opiekę nad nimi. –

+0

Ale używam ciasteczek! Mam cookieless = "UseCookies". Dziękuję za odpowiedź. Naprawdę jestem zdezorientowany - twoja sugestia działa, ale nie wiem dlaczego? – bplus

10

Ja też miał ten sam problem. Właściwie to się stało, ponieważ nie mogłem odczytać pliku cookie uwierzytelniania formularzy z javascript, po jakimś czasie było to undefined. Chciałem tylko wiedzieć, czy zostałem uwierzytelniony przez javascript.

Później okazało się, że bilet wygasł, ale nie zostałem wylogowany (również, więc chciałem to rozwiązać)! Widziałem, że twoje pytanie nie zostało odebrane, więc otworzyłem je, podczas gdy przez pół dnia rozwiązywałem swoje problemy. Oto, co wymyśliłem, co wydaje się działać.

Moja odpowiedź opiera się na tej odpowiedzi. https://stackoverflow.com/a/454639/511438 przez użytkownika ScottS

Jest to w moim projekcie ASP.NET MVC 3.

Oto mój kod logowania. Nie pokazano, niestandardowa logika uwierzytelniania użytkownika przed nim. To po prostu ustawia bilet początkowy.

publiczny klasa FormsAuthenticationService: IFormsAuthentication

public void SignIn(string userName, bool createPersistentCookie, string role) 
{ 
    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
      1,        // version 
      userName,   // user name 
      DateTime.Now,     // created 
      DateTime.Now.Add(FormsAuthentication.Timeout), // expires 
      false,     // rememberMe? 
      role      // can be used to store roles 
      ); 

    string encryptedTicket = FormsAuthentication.Encrypt(authTicket); 

    HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 
    HttpContext.Current.Response.Cookies.Add(authCookie); 
} 

w tej samej klasie, ale to metoda statyczna, który jest dostępny z global.asax

//-- this is based on https://stackoverflow.com/questions/454616/asp-net-cookies-authentication-and-session-timeouts 
internal static FormsAuthenticationTicket RefreshLoginCookie(bool retainCurrentExpiry) 
{ 
    HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
    if (authCookie == null || authCookie.Value == null) 
     return null; 

    FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(authCookie.Value); 

    DateTime expiryDate = (retainCurrentExpiry ? oldTicket.Expiration : DateTime.Now.Add(FormsAuthentication.Timeout)); 
    HttpContext.Current.Response.Cookies.Remove(FormsAuthentication.FormsCookieName); 

    var newTicket = new FormsAuthenticationTicket(oldTicket.Version, oldTicket.Name, oldTicket.IssueDate, expiryDate, 
     oldTicket.IsPersistent, oldTicket.UserData, oldTicket.CookiePath); 

    HttpCookie newAuthCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(newTicket)); 
    HttpContext.Current.Response.Cookies.Add(newAuthCookie); 

    return newTicket; 

} 

globalnego.asax

Moja personalizacja polega na tym, że żądania ajax nie odświeżają biletu uwierzytelniania formularzy. Więc jeśli siedzisz tam przez okres czasu, żądanie ajax wyloguje cię. Zmień to, jeśli chcesz, aby żądania ajaxowe utrzymywały przy życiu bilet (rozwiązuje mój problem z plikiem cookie javascript, a nie problem braku aktywności podczas wylogowywania). * (wskazówka, jeśli się wylogujesz, następnie zalogujesz się, ale wrócisz na stronę logowania, pierwsze logowanie nie określiło returnUrl w querystringu). *

protected virtual void Application_AuthenticateRequest(Object sender, EventArgs e) 
{ 
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
    if (authCookie == null || authCookie.Value == "") 
    { 
     return; 
    } 

    bool isAjax = new HttpRequestWrapper(System.Web.HttpContext.Current.Request).IsAjaxRequest(); 

    FormsAuthenticationTicket authTicket; 
    try 
    { 
     //-- THIS IS WHAT YOU WANT 
     authTicket = FormsAuthenticationService.RefreshLoginCookie(isAjax); 
    } 
    catch 
    { 
     return; 
    } 

    string[] roles = authTicket.UserData.Split(';'); 
    if (Context.User != null) Context.User = new GenericPrincipal(Context.User.Identity, roles); 

} 

Web.config tutaj jest część, gdzie mogę ustawić limit czasu sesji i limit czasu biletów

<configuration> 
    <system.web> 
     <sessionState mode="InProc" timeout="60" /> 
     <authentication mode="Forms"> 
      <forms loginUrl="~/Account/Login" timeout="60" name="ProviderMvcSession" cookieless="UseCookies" /> 
     </authentication> 
+0

Widziałem twój kod RefreshLoginCookie() ta funkcja generuje cookie auth ze starymi danymi, ale dlaczego po prostu nie mogłem tego zrozumieć. w jakiej sytuacji ludzie sięgną po takie podejście? – Mou

0

oczywistym rozwiązaniem, które można łatwo wychodził na niektórych ludzi, wyczyszczenie cookies przeglądarki lub wylogowanie powinno rozwiązać problem. Jeśli zapamiętasz mnie, to aplikacja będzie nadal logować się ze starym plikiem cookie, niezależnie od zmian wprowadzonych do wartości limitu czasu Web.Config.

Powiązane problemy