我遇到了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。这甚至可能吗?
答案 0 :(得分:5)
在服务器端,无法永久清除身份验证会话。您可以清除cookie,但如果有人复制了它,他们可以简单地重复使用它,他们就可以访问该网站。 Auth cookie是加密的验证票证,这意味着站点对它们进行解密,并验证它们是否正确解密且未过期。如果是这种情况,则auth cookie有效。
不幸的是,除了使用短期过期值并在滑动窗口上更新到期日期之外,没有办法解决这个问题,但这意味着如果用户闲置几分钟他们将不得不登录试。
没有"会话ID"与身份验证票证相关联,虽然您当然可以生成唯一ID并将其存储在票证中,然后将该ID存储在服务器上并在每个请求上进行比较以添加额外的安全层。当您要杀死该cookie时,您清除服务器上的任何ID,并且他们无法再登录,即使该票证有效。
另一方面,会话cookie确实有ID,并且与映射到该ID的内部存储相关联,因此当您清除会话时,您也会删除存储...如果您重复使用该cookie,那么它就会被&#39 ; s只是要获取空数据。您还可以通过始终使用加密Cookie和使用HTTPS来添加更多安全性。 HTTPS不会以可以获取和重新使用它们的方式存储cookie(它们使用SSL会话加密,一旦SSL会话完成,cookie就无法使用)。
另一个选择是使用非持久性cookie,这些cookie不会存储在服务器上......尽管在中间攻击中它们仍然可以被人捕获。
要理解无法解决问题的原因,您必须了解身份验证Cookie是长期存在的,并存储在用户计算机上。当您回来时,它可能是一个不同的会话。因此,了解用户是否经过身份验证的唯一方法是简单地依赖于是否可以使用服务器凭据(通常是机器密钥)来解密cookie。这意味着会话和身份验证票据之间故意没有链接。
答案 1 :(得分:1)
服务器确实忘记了与该会话相关的所有内容,因此当您使用Session.Clear()
时,该会话ID无效。
正如msdn documentation所说:
从会话状态集合中删除所有键和值
因此,即使有人使用相同的会话ID,服务器中也不会附加任何信息。
<强> [编辑] 强>
正如Erik Funkenbusch指出的那样,只有在会话中存储身份验证信息(显然)时,我的解决方案才有效。如果您的身份验证系统具有特定的cookie,那么这将无法工作。
答案 2 :(得分:1)
确保在服务器端擦除所有会话/ cookie的非编程方法是在应用程序的web.config中添加(如果不存在)或更改(如果存在)机器密钥
可以通过IIS管理器选择一个应用程序来完成,在ASP.NET部分选择“Machine Key”,取消选中所有复选框,然后点击Generate Keys,然后点击Apply
请注意,这不是针对单个用户,而是会触发所有用户。
答案 3 :(得分:0)
如果你指向浏览器后退按钮,我使用下面的代码(vb,但你可以转换它):
<强>的web.config:强>
<sessionState timeout="20" regenerateExpiredSessionId="true"/>
avsessexp.js (如果15分钟后处于非活动状态,则自动刷新页面):
var BeatTimer;
function StartCheck() {
if (BeatTimer == null) {
BeatTimer = setInterval("CheckBeat()", 900000);
}
}
function CheckBeat() {
PageMethods.PokePage();
}
并在每个页面(StartCheck
)
<body onload="StarCheck();">
函数
在我放入的每个页面的标题中:
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache, no-store, max-age=0, must-revalidate" />
<meta http-equiv="expires" content="0" />
<强>的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
并且,在每个页面(代码隐藏)中:
<System.Web.Services.WebMethod(EnableSession:=True)> 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
将阻止返回上一页,并始终将用户重定向到登录页面。
在每个页面/母版页<asp:ScriptManager runat="server" id="sm1" EnablePageMethods="True"><asp:ScriptManager>
P.S。抱歉我的英语不好。