我希望用户能够通过HTTP基本身份验证模式进行登录。
问题是,我也希望他们能够再次退出登录——奇怪的是,浏览器似乎不支持这一点。
这被认为是社交黑客风险——用户离开他们的机器解锁并保持浏览器打开状态,其他人可以轻松地以他们的身份访问该网站。请注意,仅关闭浏览器选项卡是不足以重置令牌的,因此用户可能会忽略这个简单的事情。
因此,我想出了一个解决方法,但它是一个完全混乱的方法:
1)将他们重定向到注销页面
2)在该页面上启动脚本来ajax加载另一个带有虚假凭据的页面:
问题是,我也希望他们能够再次退出登录——奇怪的是,浏览器似乎不支持这一点。
这被认为是社交黑客风险——用户离开他们的机器解锁并保持浏览器打开状态,其他人可以轻松地以他们的身份访问该网站。请注意,仅关闭浏览器选项卡是不足以重置令牌的,因此用户可能会忽略这个简单的事情。
因此,我想出了一个解决方法,但它是一个完全混乱的方法:
1)将他们重定向到注销页面
2)在该页面上启动脚本来ajax加载另一个带有虚假凭据的页面:
$j.ajax({
url: '<%:Url.Action("LogOff401", new { id = random })%>',
type: 'POST',
username: '<%:random%>',
password: '<%:random%>',
success: function () { alert('logged off'); }
});
3) 第一次请求应该总是返回401状态码(以强制使用新凭证),接下来只接受虚拟凭证:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOff401(string id)
{
// if we've been passed HTTP authorisation
string httpAuth = this.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(httpAuth) &&
httpAuth.StartsWith("basic", StringComparison.OrdinalIgnoreCase))
{
// build the string we expect - don't allow regular users to pass
byte[] enc = Encoding.UTF8.GetBytes(id + ':' + id);
string expected = "basic " + Convert.ToBase64String(enc);
if (string.Equals(httpAuth, expected, StringComparison.OrdinalIgnoreCase))
{
return Content("You are logged out.");
}
}
// return a request for an HTTP basic auth token, this will cause XmlHttp to pass the new header
this.Response.StatusCode = 401;
this.Response.StatusDescription = "Unauthorized";
this.Response.AppendHeader("WWW-Authenticate", "basic realm=\"My Realm\"");
return Content("Force AJAX component to sent header");
}
4) 现在随机字符串凭据已被浏览器接受并缓存。当用户访问另一个页面时,它会尝试使用这些凭据,但会失败,然后提示正确的凭据。
请注意,我的代码示例使用jQuery和ASP.Net MVC,但使用任何技术栈都应该是可能的。
在IE6及以上版本中还有另一种方法:
document.execCommand("ClearAuthenticationCache");
然而,这样会清除所有的身份验证 - 他们退出我的站点后,也会退出他们的电子邮件。所以这个方法行不通。
有没有更好的方法?
我看到了其他问题,但它们是两年前的 - 现在在IE9、FX4、Chrome等浏览器中是否有更好的方法?
如果没有更好的方法,这个方法可靠吗?有没有办法使其更加健壮?