清除cookie,会话和formsauth后,Asp.net在注销时删除服务器上的会话

我遇到了asp.net的安全问题。 在注销时,我想确保会话被销毁,以便有人不能使用相同的sessionid和auth cookie并在那里编辑cookie,服务器仍然会响应会话。

FormsAuthentication.SignOut(); Session.Abandon(); Session.RemoveAll(); Session.Clear(); 

我也试图给客户写新的cookie

 // clear authentication cookie HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, ""); cookie1.Expires = DateTime.Now.AddYears(-1); Response.Cookies.Add(cookie1); HttpCookie cookie2 = new HttpCookie("ASP.NET_SessionId", ""); cookie2.Expires = DateTime.Now.AddYears(-1); Response.Cookies.Add(cookie2); 

我已尝试在不同的顺序使用以下,仍然没有骰子。 如果我使用原始的sessionid和Auth cookie,我仍然可以登录。 我希望服务器在我注销时完全忘记该sessionid。 这有可能吗?

服务器确实忘记了与该会话相关的所有内容,因此在使用Session.Clear()时使该会话ID无效。

正如msdn文档所说:

从会话状态集合中删除所有键和值

因此,即使有人使用相同的会话ID,服务器中也不会附加任何信息。

[编辑]

正如Erik Funkenbusch指出的那样,只有在会话中存储身份validation信息时,我的解决方案才有效(显然)。 如果您的身份validation系统具有特定的cookie,则无法使用此function。

在服务器端,无法永久清除身份validation会话。 您可以清除cookie,但如果有人复制了它,他们可以简单地重复使用它,他们就可以访问该网站。 Auth cookie是加密的validation票证,这意味着站点对它们进行解密,并validation它们是否正确解密且未过期。 如果是这种情况,则auth cookie有效。

不幸的是,除了使用短期过期值并在滑动窗口上更新到期日期之外,没有办法解决这个问题,但这意味着如果用户闲置几分钟,他们将不得不再次登录。

没有与身份validation票证关联的“会话ID”,尽管您当然可以生成唯一ID并将其存储在票证中,然后将该ID存储在服务器上并在每个请求上进行比较以添加额外的安全层。 当您要杀死该cookie时,您清除服务器上的任何ID,即使该票证有效,它们也无法再登录。

另一方面,会话cookie确实有id,并且与映射到该ID的内部存储相关联,因此当您清除会话时,您也会删除存储…如果您重复使用该cookie,那么它只会获取空数据。

您还可以通过始终使用加密的Cookie和使用HTTPS来增加安全性。 HTTPS不会以可以获取和重新使用它们的方式存储cookie(它们使用SSL会话加密,一旦SSL会话完成,cookie就无法使用)。

另一种选择是使用非持久性cookie,这些cookie不会存储在服务器上……尽管在中间攻击中它们仍然可以被人捕获。

要理解无法解决问题的原因,您必须了解身份validationcookie应该是长期使用的,并存储在用户计算机上。当您回来时,它可以是不同的会话。 因此,了解用户是否经过身份validation的唯一方法是简单地依赖于是否可以使用服务器凭据(通常是计算机密钥)解密cookie。 这意味着会话和身份validation票据之间故意没有链接。

确保在服务器端擦除所有会话/ cookie的非编程方法是在应用程序的web.config中添加(如果不存在)或更改(如果存在)机器密钥。

可以通过IIS管理器选择一个应用程序来完成,在ASP.NET部分选择“Machine Key”,取消选中所有复选框,然后点击Generate Keys,然后点击Apply

请注意,这不是针对单个用户,而是会触发所有用户。

机器密钥 - 生成

如果你指向浏览器后退按钮,我使用下面的代码(vb,但你可以转换它):

web.config中:

  

avsessexp.js (自动刷新页面,如果15分钟后无效):

 var BeatTimer; function StartCheck() { if (BeatTimer == null) { BeatTimer = setInterval("CheckBeat()", 900000); } } function CheckBeat() { PageMethods.PokePage(); } 

并在每个页面中调用StartCheck函数(

在我放的每页的标题中:

    

Module1.vb中

 Public Sub CheckSession() With HttpContext.Current .Response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(-1)) .Response.Cache.SetCacheability(HttpCacheability.NoCache) .Response.Cache.SetNoStore() If .Session.IsNewSession = True Then LogOut() 'there You can put some code checking is user logged, ... End With End Sub Public Sub LogOut() With HttpContext.Current .Session.RemoveAll() .Session.Clear() .Session.Abandon() Try .Response.Cookies.Add(New System.Web.HttpCookie("ASP.NET_SessionId", "")) Catch ex As Exception End Try .Response.Redirect("Default.aspx") End With End Sub 

并且,在每个页面(代码隐藏):

  Public Shared Sub PokePage() CheckSession() End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then CheckSession() End Sub 

如果您在注销后尝试单击浏览器后退按钮, CheckUser将阻止返回到prev页面,并始终将用户重定向到登录页面。

在每个页面/母版页上使用非常重要

抱歉我的英语不好。