如何在ASP.NET会话Cookie上设置安全标志,以便它只通过HTTPS传输,而不是通过纯HTTP传输?
销毁会话和删除其值有什么区别?你能举一个证明这个的例子吗?
我搜索了这个问题,但没有掌握全部答案.一些答案是:
Session.Abandon() 破坏会话Session.Clear() 只删除所有值一位朋友告诉我这个:
清除会话不会取消设置会话,它仍然存在与用户相同的ID,但只是清除了值.
放弃将完全破坏会话,这意味着您需要先开始一个新会话,然后才能在该会话中为该用户存储更多值.
以下代码有效,不会抛出任何异常.
Session.Abandon();
Session["tempKey1"] = "tempValue1";
Run Code Online (Sandbox Code Playgroud)
当您放弃会话时,您(或更确切地说是用户)将获得一个新的SessionId
当我测试Session时,当我放弃会话时它不会做任何改变.
我发现一个区别:
session.Abandon()引发Session_End事件
当用户单击注销时,我将用户重定向到登录页面但是我认为它不会清除任何应用程序或会话,因为当用户重新登录时所有数据都会保留.
目前,登录页面具有登录控件,页面上的代码仅通过登录Authenticate连接.
有人可以指导我一个关于处理ASP.NET网站登录和退出的好教程或文章吗?
据我所知,目前的情况如下:
你会选择什么?
UPDATE
我们最终与Acunetix团队的一些程序员进行了会面,他们意识到他们的代码中可能存在一些错误,这些错误导致它在扫描中显示为一个问题而不是实际问题.普遍的共识是忽略扫描结果并使用开箱即用的ASP.NET会话ID生成,因为它应该对我们的站点足够安全.
@Vasile Bujac,因为你的答案是唯一一个,并提到使用ASP.NET标准解决方案,我把它作为答案,但感谢大家的帮助.
我们在工作时使用Acunetix的Retina扫描仪对我们的应用程序进行安全扫描.它告诉我们,我们的会话ID不够随机且太可预测.我不确定ASP.NET默认情况下如何生成会话ID(我认为它仍然是GUID?),但我继续实现了扩展SessionIDManager类并重写CreateSessionID和Validate方法以使用Guid的方法正如本MSDN文章中所述.
虽然这使得它稍微随机,但仍然没有产生Acunetix的"期望"效果.我甚regenerateExpiredSessionId="true"至将属性添加到web.config并且没有任何效果.我有一种感觉,我可能需要刻意打电话Session.Abandon()来真正清除会话并获得一个新ID.问题是我必须在用户登录之前调用它,因为它是唯一一种知道用户正在开始新会话的防故障方式.所以我无法在会话中设置任何内容,直到下一页加载了Abandon方法的工作方式,这意味着中间页面不是很理想,但可以做到这一点.
有没有人经历过这个或成功实施过修复?
另外,仅仅是一个FYI,我们不使用成员资格/表单身份验证,我们只是在有人登录时创建一个新的自定义用户类,并将其保存在会话中供以后使用.
来自Acunetix的报告:
描述: 表现出低熵("随机性")的会话令牌通常容易受到预测攻击.不安全令牌可能是由于伪随机数生成器,基于时间的值,静态值或基于用户属性(用户名或用户ID)的值不足造成的.这意味着攻击者可以在短时间内监视应用程序并收集它创建的会话令牌后猜测有效的会话令牌.如果攻击者为另一个用户确定了有效的会话令牌,则可以查看,修改或删除任意用户的数据,而无需猜测受害者的用户名或密码.因此,推断有效会话令牌的能力使攻击者能够绕过登录页面并避免暴力破解帐户的需要.此外,即使受害者当前未登录到应用程序,静态令牌也可以使攻击者能够定位用户.这增加了攻击者可以攻击的受害者群.
会话令牌应使用强大的随机数生成器创建,并从大量数字中收集.例如,如果操作系统的rand()函数可以产生统计上均匀分布的32位值,那么它通常就足够了.会话令牌不佳是增量的,依赖于用户的帐户ID,仅使用时间戳,或具有其他高度确定性的信息.保护会话令牌安全性的其他方法是始终通过SSL传输它们,在一段时间后自动使令牌到期,并在用户退出应用程序时显式使令牌到期.
建议:如果会话值表现出强烈的随机性,但是从一小部分值中选择,则攻击者更有可能简单地猜测一个有效的令牌.通过实现几种互补技术,可以改进Web应用程序的会话管理:
我有一个使用Form的身份验证的应用程序,当用户登录时,我检索用户的实际名称并将其分配给会话变量,如下所示:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
Session["Name"] = client.GetName(model.UserName);
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToAction("Index", "Home");
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,它会显示在我的索引视图中,如下所示:
<h3>Welcome, @Session["Name"]</h3>
Run Code Online (Sandbox Code Playgroud)
所以,如果我的名字是鲍勃,它会在我的视图中输出"欢迎,鲍勃",这很好.但是,一旦我离开页面或关闭我的浏览器并在几分钟后返回,似乎这些Session变量已被销毁,因为它只是输出"欢迎",但我仍然登录,所以我的会话没有被销毁?我在web.config中将会话设置为在60分钟后销毁:
<sessionState regenerateExpiredSessionId="true" timeout="60" />
Run Code Online (Sandbox Code Playgroud)
只有当我在登录时检查"记住我"框时才会发生这种情况,因为我猜这会保留一个cookie客户端,因此当我重新打开浏览器时我仍然登录但是创建了一个新的会话ID,因为我Response.Write(Session.SessionID)在我的我关闭浏览器之前的索引页面和ID与我重新打开它时的ID不同.如果我不检查我的"记住我"框,那么在重新打开浏览器时我将被迫再次登录
我正在实现一个会话结构.
我有一个ConcurrentDictionary服务器端保持所有<SessionId, UserSession>对.
建立新连接时,会根据RememberMe选项将cookie分配给客户端浏览器,perm或temp .
当客户端调用该LogOut函数时,它会从字典中删除会话.
但是,当客户端浏览器被简单地关闭或崩溃,并且cookie丢失或过期或删除时,内存中的服务器端会话对象将保留在字典中并变为重影.随着时间的推移,这些鬼魂会堆积起来.
我的问题是,如何改进设计,以便在死亡会话过期后将其清理干净?
我想过让计时器服务运行一个清洁计划,但感觉不优雅.有没有更简单的方法来做到这一点,而不依赖于外部服务?
我正在使用asp.net并已将会话配置为存储在SQL Server中.我的项目有很多对象和几个linq-to-sql dbml.我已将所有这些配置为单向序列化,并进行了一些自定义更改.
当我运行应用程序时,我在application_error事件处理程序中不断收到此错误
在程序集'App_Code.thzd8p2j中输入'Data.Karaoke.spCWP_SelUserPrivilegesResult',Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null'未标记为可序列化.
从错误中我不确定它是否来自dbml.designer.cs文件,这是代码:
[Function(Name="dbo.spCWP_SelUserPrivileges")]
public ISingleResult<spCWP_SelUserPrivilegesResult> spCWP_SelUserPrivileges([Parameter(Name="IDCWPUser", DbType="Int")] System.Nullable<int> iDCWPUser)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), iDCWPUser);
return ((ISingleResult<spCWP_SelUserPrivilegesResult>)(result.ReturnValue));
}
Run Code Online (Sandbox Code Playgroud)
和
[DataContract()]
public partial class spCWP_SelUserPrivilegesResult
{
private int _IDTypeCWPModule;
private string _TypeKey;
private bool _Security;
public spCWP_SelUserPrivilegesResult()
{
}
[Column(Storage="_IDTypeCWPModule", DbType="Int NOT NULL")]
[DataMember(Order=1)]
public int IDTypeCWPModule
{
get
{
return this._IDTypeCWPModule;
}
set
{
if ((this._IDTypeCWPModule != value))
{
this._IDTypeCWPModule = value;
}
}
}
[Column(Storage="_TypeKey", DbType="VarChar(10) NOT NULL", …Run Code Online (Sandbox Code Playgroud) 请帮助我,值是存储在特定用户的会话中,当我从cshtml检索会话值时,它显示PC用户名而不是数据库中存在的特定用户名.请建议会话代码以显示特定的用户名.我在Cotrtoller中使用此代码.
{public ActionResult LogIn(Models.Tbl_Users user)
{
Session["Username"] = user.UserName;
var sessionval = Session["Username"].ToString();
if (!ModelState.IsValid)
{
if (Isvalid(user.UserName, user.UserPassword))
{
FormsAuthentication.SetAuthCookie(user.UserName, false);
string status = Session["Username"].ToString();
if (status == "admin")
{
// return RedirectToAction("adminpage", "UserLogIn");
return RedirectToAction("adminpage", "UserLogin");
}
else
{
return RedirectToAction("userpage", "UserLogIn");
} }
Run Code Online (Sandbox Code Playgroud)
这是我的cshtml代码:
{
@Html.AntiForgeryToken()
@if (Request.IsAuthenticated)
{
<strong>@Html.Encode(User.Identity.Name)</strong>
@Html.ActionLink("Log Out","LogOut","UserLogIn")
}
Run Code Online (Sandbox Code Playgroud)
}
asp.net-session ×10
asp.net ×5
c# ×5
session ×3
.net ×2
.net-4.5 ×1
asp.net-mvc ×1
azure ×1
linq-to-sql ×1
sessionid ×1
sql-server ×1
ssl-security ×1