asp.net - asp - Evitar que el tiempo de vencimiento de FormsAuthentication aumente
web config forms authentication (3)
Después de pensarlo un poco, me desvié de intentar alterar la cookie o crear una segunda cookie o anular la cookie cambiando la Session.Timeout. Creo que en realidad puede ser más fácil usar un temporizador, usando System.Timers. Los métodos para el temporizador siempre se pueden poner en una clase separada si lo desea.
using System.Timers;
public partial class MyPage:Page
{
private System.Timers.Timer timer;
protected void Page_Load(object sender, EventArgs e)
{
SetTimer();
}
private void SetTimer()
{
// Interval is set in milliseconds- set as you please.
timer = new System.Timers.Timer(1000 * 60);
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true;
timer.Enabled = true;
}
// In this handler, stop the timer and call a method to clear all cookies.
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
timer.Stop();
ClearAllCookies();
}
// Method to clear all cookies. There may be a simpler way to do this, you are vague about your cookies, so I supplied a clear all.
public void ClearAllCookies()
{
HttpCookie cookie;
string cookieName;
int cookieCnt = Request.Cookies.Count;
for(int i = 0; i < cookieCnt; i++)
{
cookieName = Request.Cookies[i].Name;
cookie = new HttpCookie(cookieName);
// This causes the cookie to expire
cookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(cookie);
}
Response.Redirect("LogIn.aspx");
}
}
Editar
O use un método que registre al usuario. De cualquier manera, terminará la sesión sin tener que manipular la autenticación del usuario durante el resto del sitio web, excepto para finalizarla si la sesión expira en esta página en particular.
public void ForceLogOff(){
Session.Clear();
Session.Abandon();
Session.RemoveAll();
// Do here whatever you need to do.
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
Response.Redirect("LogIn.aspx");
}
Cómo terminas la sesión depende de ti. Esto le proporciona una forma de anular el problema de caducidad móvil y establecer un tiempo de espera personalizado desde una sola página.
Tengo un sitio relativamente simple basado en WebForms que usa la Autenticación de formularios:
<authentication mode="Forms">
<forms loginUrl="login.aspx" defaultUrl="secure/home.aspx" name=".AdminSite" />
</authentication>
Como no se menciona explícitamente, slidingExpiration
se establece de forma predeterminada en true y, por lo tanto, un usuario no se desconecta mientras siga navegando por el sitio.
Sin embargo, me gustaría que una página específica no incremente el tiempo de caducidad. ¿Es esto posible, ya sea dentro de web.config
o en código? Las únicas sugerencias que he visto mencionan establecer slidingExpiration
en false
, que se aplicaría en todo el lateral.
La cookie de autenticación se establece usando:
FormsAuthentication.RedirectFromLoginPage(username, False)
y por lo tanto, alterar la cookie de autenticación en sí no es práctico.
La expiración FormsAuthentication
se logra mediante el módulo FormsAuthentication
al volver a emitir la cookie cuando sea necesario. Para evitar el deslizamiento, debe evitar que se produzca la renovación de cookies.
Esto se puede hacer simplemente eliminando la cookie FormsAuthentication
de la respuesta.
A continuación se muestra el código detrás de un formulario web muy simple. La página aspx
tiene un div
que muestra el resultado del evento Page_Load
.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
testDiv.InnerHtml = "Hi, cookie is: " + HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value;
testDiv.InnerHtml += "<br />";
var ticket = FormsAuthentication.Decrypt( HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
testDiv.InnerHtml += "Expires: " + ticket.Expiration.ToString("yyyy-MM-dd HH:mm:ss");
if(Response.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName))
testDiv.InnerHtml += "<br />Forms auth is trying to update the cookie in this response";
}
protected void Page_Prerender(object sender, EventArgs e)
{
if (Response.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName))
Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
}
}
El evento Page_Prerender
elimina la cookie FormsAuthentication
de la respuesta si está presente, lo que impide el deslizamiento.
FormsAuthentication
esto estableciendo el tiempo de espera para FormsAuthentication
en dos minutos. Luego empiezo a depurar e iniciar sesión. Luego, sigo refrescando la página en cuestión.
Dado que FormsAuthentication
no actualiza la cookie a menos que se haya FormsAuthentication
la mitad del tiempo de caducidad, lo que ocurre es que, durante el primer minuto, la página seguirá mostrando la misma cookie cifrada y el mismo tiempo de caducidad. Después de un poco más de un minuto, la página informará que FormsAuthentication
está intentando renovar la cookie. Pero Page_Prerender
elimina la cookie para que no se envíe. Después de otro minuto, será redirigido a la página de inicio de sesión.
Probar lo mismo pero eliminar el método Page_Prerender
muestra que la cookie se ha cambiado y el tiempo de caducidad se actualiza después de aproximadamente un minuto.
Puede establecer la fecha de caducidad de la cookie de respuesta a la fecha de caducidad de la cookie de solicitud, sobrescribiendo efectivamente lo que el sistema está haciendo para esa página específica.