我希望用户能够通过 HTTP Basic 身份验证模式登录。
问题是我还希望他们能够再次注销 - 奇怪的是浏览器似乎不支持这一点。
这被认为是一种社交黑客风险 - 用户将他们的机器解锁并打开他们的浏览器,其他人可以轻松地以他们的身份访问该网站。请注意,仅关闭浏览器选项卡不足以重置令牌,因此用户可能很容易错过。
所以我想出了一个解决方法,但它完全是一个难题:
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");
但是,这会清除所有身份验证 - 他们从我的网站注销,他们也从他们的电子邮件中注销。所以就这样了。
有没有更好的方法来做到这一点?
我已经看到了其他 问题,但它们已经 2 岁了 - 现在在 IE9、FX4、Chrome 等中有没有更好的方法?
如果没有更好的方法可以做到这一点,是否可以依靠这个结块?有什么办法让它更健壮吗?