nic*_*ckc 7 security asp.net-mvc forms-authentication
我正在尝试使用ASP.NET MVC 2.0和表单身份验证来保护我正在开发的网站.为了保护表单身份验证cookie,我想将requiresSSL属性设置为true,这样只有当连接在SSL下时才由浏览器发送cookie,并且显然确保所有需要授权的资源都在SSL下.
我的问题是我们正在使用应用程序请求路由来实现许多功能,一个是SSL卸载,因此当请求到达我们服务器场中的任何Web服务器时,请求不再是SSL,并且FormsAuthentication.SetAuthCookie方法失败,因为指定requiresSSL时,需要SSL连接来设置cookie.
任何人对这里的工作都有任何想法!
谢谢
所以我有一个解决办法,但是如果有人有更好的想法,请随时发表评论。本质上,您需要在请求结束时拦截响应,并手动设置表单身份验证 cookie 上的 Secure 属性,非常明显,您还需要将表单身份验证配置中的 requireSSL 属性设置为 false。另请记住,我们不想为经过身份验证的用户启用整个站点的 HTTPS,因此需要解决此问题。
这种方法有一些注意事项以及一些需要注意的事项。
我在测试过程中发现表单身份验证 cookie 始终写入响应中,因此我不断用空身份验证 cookie 覆盖浏览器中的有效身份验证 cookie,为了解决此问题,我在 HTTP 模块中包含了一些逻辑来解决此问题,请参阅下面的代码片段。
对需要授权的应用程序的所有请求都必须在 SSL 下进行,否则请求将不会包含身份验证 cookie 来对用户进行身份验证。
因为您只传递 SSL 请求的身份验证 cookie,所以您将需要另一种机制来告诉您的应用程序当前用户在浏览网站的非 SSL 区域时已通过身份验证,我已使用一个附加 cookie 来实现此功能,该 cookie 在用户登录,并且没有设置到期日期,因此将在用户会话结束时到期,当然,如果用户注销,此 cookie 将被删除。
下面是在 HTTP 模块中实现的影响上述内容的逻辑,我在过去的几个小时里一直在测试它,还没有遇到任何问题,如果我这样做了,我一定会更新这篇文章!
如果用户刚刚登录,我们应该只向客户端发送身份验证 cookie,这是逻辑
private void EndRequest(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
if (ValidRequest(application.Request) && application.Response.Cookies.Count > 0)
{
//only do the below if the user is not logging out the site, if the user is logging out we can
//leave the default forms authentication behaviour which is to expire the auth cookie
if (application.Request.AppRelativeCurrentExecutionFilePath != "~/authentication/logoff")
{
var requestAuthCookie = application.Request.Cookies[FormsAuthentication.FormsCookieName];
var responseAuthCookie = application.Response.Cookies[FormsAuthentication.FormsCookieName];
if (requestAuthCookie != null && responseAuthCookie != null && responseAuthCookie.Value.IsNullOrEmpty())
{
application.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
}
else if (responseAuthCookie != null && !responseAuthCookie.Value.IsNullOrEmpty())
{
responseAuthCookie.Secure = true;
application.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
application.Response.Cookies.Add(responseAuthCookie);
}
else if (responseAuthCookie == null || responseAuthCookie.Value.IsNullOrEmpty())
{
application.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)