2012-01-24 30 views
15

Estoy usando FormsAuthentication, tengo problemas para configurar el valor de TimeOut.Tiempo de espera no funciona en ASP.Net MVC FormsAuthentication

He visto algunas otras publicaciones relacionadas con esto, pero no parecen ser exactamente mi problema o la solución sugerida no ayuda.

Mi web.config tiene la siguiente:

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

he puesto un AuthorizeAttribute en los controladores que quiere asegurar.

Puedo ver la cookie .ASPXAUTH (usando FireCookies) y puedo ver que está configurado para caducar en 1 minuto después de un inicio de sesión.

Si puedo depurar a través de mi código Veo que FormsAuthentication.Timeout = 1.

Sin embargo, no parece mi boleto para el tiempo de espera de 1 minuto. Después de 1 minuto de inactividad aún puedo buscar controladores con AuthorizeAttribute.

De hecho, puedo eliminar la cookie .ASPXAUTH utilizando FireCookies y aún puedo buscar controladores con un atributo AuthorizeAttribute.

Extrañamente después de estar inactivo durante mucho tiempo (lo siento, no tengo una hora exacta - ¡Estaba afuera para el almuerzo!), Se produce el TimeOut y me redireccionan a la pantalla de inicio de sesión.

¿Alguna idea?

Respuesta

0

Se trata de cuánto tiempo es el tiempo de espera de su sesión. Predeterminado es de 20 minutos y se puede cambiar en web.config como esto:

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

Pero el estado de la sesión es independiente de la cookie AuthenticationTicket/.ASPXAUTH. Al menos creo que es ?! – bplus

+0

si no está utilizando cookies para almacenar estos datos, entonces la sesión es responsable de cuidarlo. –

+0

¡Pero estoy usando cookies! Tengo cookieless = "UseCookies". Gracias por responder. Estoy realmente confundido por esto, tu sugerencia funciona pero ¿no sé por qué? – bplus

10

yo también tenía el mismo problema. En realidad, se produjo porque no pude leer la cookie de autenticación de formularios de javascript, fue después de un tiempo undefined. Solo quería saber si me autenticaron a través de JavaScript.

Más tarde descubrí que el ticket había expirado, pero no me estaban desconectando (¡también, así que quería resolverlo también)! Vi que su pregunta no había sido respondida, así que la mantuve abierta mientras resolvía mis problemas durante medio día. Lo siguiente es lo que se me ocurrió que parece estar funcionando.

Mi respuesta se basa en esta respuesta. https://stackoverflow.com/a/454639/511438 por usuario ScottS

Esto está en mi proyecto ASP.NET MVC 3.

Aquí está mi código de inicio de sesión. No se muestra, la lógica de autenticación de usuario personalizada anterior. Esto solo establece el ticket inicial.

FormsAuthenticationService clase pública: 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); 
} 

en la misma clase, pero un método estático que se accede desde 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; 

} 

global.asax

Mi personalización proviene de que las solicitudes ajax no actualizan el ticket de autenticación de formularios. Entonces, si te sientas allí durante el tiempo de espera, una solicitud de Ajax te desconectará. Cámbialo si quieres que las solicitudes ajax mantengan vivo el ticket (se dirige a mi problema de cookies de JavaScript, no a tu problema de inactividad). * (consejo, si se cierra la sesión, luego inicia sesión, pero vuelve a la página de inicio de sesión, el primer inicio de sesión no especificó una returnUrl en la cadena de consulta). *

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 aquí es la parte en la que poner el tiempo de sesión y el tiempo de espera de entradas

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

he visto su código RefreshLoginCookie() esta función genera una cookie de autenticación con datos antiguos, pero por qué simplemente no podía entender. ¿en qué tipo de situación la gente iría por este enfoque? – Mou

0

Una solución obvia que podrían ser fácilmente miró por algunas personas, la limpieza de las cookies del navegador o cerrar sesión debería resolver el problema. Si la opción recordarme está marcada, la aplicación seguirá ingresando con la cookie anterior, independientemente de los cambios realizados en el valor de tiempo de espera de Web.Config.

Cuestiones relacionadas