防止 FormsAuthentication 到期时间增加
Preventing FormsAuthentication expiry time from increasing
我有一个使用表单身份验证的相对简单的基于 WebForms 的站点:
<authentication mode="Forms">
<forms loginUrl="login.aspx" defaultUrl="secure/home.aspx" name=".AdminSite" />
</authentication>
由于没有明确提及,slidingExpiration
默认设置为 true,因此只要用户仍在网站上导航,他们就不会注销。
但是,我希望特定页面不增加到期时间。这可能在 web.config
内还是在代码中?我看到的唯一建议是将 slidingExpiration
设置为 false
,这将适用于横向。
身份验证 cookie 设置使用:
FormsAuthentication.RedirectFromLoginPage(username, False)
因此更改身份验证 cookie 本身是不切实际的。
您可以将响应 cookie 的到期日期设置为请求 cookie 的到期日期,从而有效地覆盖系统为该特定页面所做的操作。
经过一番思考,我放弃了尝试更改 cookie 或创建第二个 cookie 或通过更改 Session.Timeout 覆盖 cookie。我认为使用计时器实际上可能更容易,使用 System.Timers。如果你愿意,定时器的方法总是可以放在一个单独的 class 中。
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");
}
}
编辑
或使用注销用户的方法。无论哪种方式,您都将结束会话,而无需 fiddle 在网站其余部分的持续时间内通过用户身份验证,除非会话在此特定页面上超时时结束会话。
public void ForceLogOff(){
Session.Clear();
Session.Abandon();
Session.RemoveAll();
// Do here whatever you need to do.
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
Response.Redirect("LogIn.aspx");
}
如何结束会话由您决定。这为您提供了一种方法来解决滑动过期问题,并仅在一页内设置自定义超时。
FormsAuthentication
模块通过在必要时重新发布 cookie 来实现滑动过期。为了防止滑动,你需要防止cookie更新发生。
这可以通过简单地从响应中删除 FormsAuthentication
cookie 来完成。
下面是一个非常简单的 Web 表单的隐藏代码。 aspx
页面有一个 div
显示 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);
}
}
Page_Prerender
事件从响应中删除 FormsAuthentication
cookie(如果存在),从而防止滑动。
我通过将 FormsAuthentication
的超时设置为两分钟来对此进行测试。然后我开始调试并登录。然后我不断刷新有问题的页面。
由于 FormsAuthentication
除非过期时间过半才更新 cookie,因此在第一分钟内,页面将继续显示相同的加密 cookie 和相同的过期时间。一分多钟后,页面将报告 FormsAuthentication
正在尝试更新 cookie。但是 Page_Prerender
删除了 cookie,所以它不会被发送。一分钟后,您将被重定向到登录页面。
测试相同但删除 Page_Prerender
方法显示 cookie 已更改并且过期时间在大约一分钟后更新。
我有一个使用表单身份验证的相对简单的基于 WebForms 的站点:
<authentication mode="Forms">
<forms loginUrl="login.aspx" defaultUrl="secure/home.aspx" name=".AdminSite" />
</authentication>
由于没有明确提及,slidingExpiration
默认设置为 true,因此只要用户仍在网站上导航,他们就不会注销。
但是,我希望特定页面不增加到期时间。这可能在 web.config
内还是在代码中?我看到的唯一建议是将 slidingExpiration
设置为 false
,这将适用于横向。
身份验证 cookie 设置使用:
FormsAuthentication.RedirectFromLoginPage(username, False)
因此更改身份验证 cookie 本身是不切实际的。
您可以将响应 cookie 的到期日期设置为请求 cookie 的到期日期,从而有效地覆盖系统为该特定页面所做的操作。
经过一番思考,我放弃了尝试更改 cookie 或创建第二个 cookie 或通过更改 Session.Timeout 覆盖 cookie。我认为使用计时器实际上可能更容易,使用 System.Timers。如果你愿意,定时器的方法总是可以放在一个单独的 class 中。
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");
}
}
编辑
或使用注销用户的方法。无论哪种方式,您都将结束会话,而无需 fiddle 在网站其余部分的持续时间内通过用户身份验证,除非会话在此特定页面上超时时结束会话。
public void ForceLogOff(){
Session.Clear();
Session.Abandon();
Session.RemoveAll();
// Do here whatever you need to do.
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
Response.Redirect("LogIn.aspx");
}
如何结束会话由您决定。这为您提供了一种方法来解决滑动过期问题,并仅在一页内设置自定义超时。
FormsAuthentication
模块通过在必要时重新发布 cookie 来实现滑动过期。为了防止滑动,你需要防止cookie更新发生。
这可以通过简单地从响应中删除 FormsAuthentication
cookie 来完成。
下面是一个非常简单的 Web 表单的隐藏代码。 aspx
页面有一个 div
显示 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);
}
}
Page_Prerender
事件从响应中删除 FormsAuthentication
cookie(如果存在),从而防止滑动。
我通过将 FormsAuthentication
的超时设置为两分钟来对此进行测试。然后我开始调试并登录。然后我不断刷新有问题的页面。
由于 FormsAuthentication
除非过期时间过半才更新 cookie,因此在第一分钟内,页面将继续显示相同的加密 cookie 和相同的过期时间。一分多钟后,页面将报告 FormsAuthentication
正在尝试更新 cookie。但是 Page_Prerender
删除了 cookie,所以它不会被发送。一分钟后,您将被重定向到登录页面。
测试相同但删除 Page_Prerender
方法显示 cookie 已更改并且过期时间在大约一分钟后更新。