请尝试在 global.cs 文件中进行设置:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier
这将在您的令牌中添加名称标识符。
至于双重登录问题,尝试使用脚本记录原始提交的日期和时间,以防止使用相同令牌进行第二次提交。
jQuery.fn.preventDoubleSubmission = function() {
$(this).on('submit',function(e){
var $form = $(this);
if ($form.data('submitted') === true) {
e.preventDefault();
} else {
$form.data('submitted', true);
}
});
return this;
};
所以我们知道一件事情; 用户喜欢后退按钮并且有双击的习惯,这是AntiforgeryToken的一个大问题。
但是根据您的应用程序所做的事情,有办法限制他们的强迫症。其中最简单的方法是尽力使访问者不觉得需要“倒带”他们的请求以更改它。
确保表单错误消息清晰简明,以确保用户知道哪里出了问题。上下文错误会给予额外的加分。
始终在表单提交之间保持表单状态。除了密码或信用卡号码外,由于MVC表单助手,没有任何借口。
如果表单分散在选项卡或隐藏的div中,例如在Angular或ember.js等SPA框架中使用的那些表单,请聪明地显示控制器布局或表单,以便在显示错误时显示实际来源的控制器布局或表单。不要只是将它们指向主控制器或第一个选项卡。
“发生了什么?”- 让用户知情
当一个AntiForgeryToken无法验证时,您的网站将抛出System.Web.Mvc.HttpAntiForgeryException类型的异常。
如果您已正确设置,则已打开友好的错误,并且这意味着您的错误页面不会显示异常,并显示一个漂亮的错误页面,告诉他们发生了什么。
您可以通过捕获HttpAntiForgeryException来使这更容易,至少为用户提供一个针对这些异常的更具信息性的页面。
private void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is HttpAntiForgeryException)
{
Response.Clear();
Server.ClearError();
Response.Redirect("/error/antiforgery", true);
}
}
你的/error/antiforgery
视图可以告诉他们:“对不起,您尝试提交相同的信息两次”。
另一个想法是记录错误并将用户返回到登录屏幕:
创建一个HandleAntiforgeryTokenErrorAttribute
类,覆盖OnException方法。
HandleAntiforgeryTokenErrorAttribute.cs:
public class HandleAntiforgeryTokenErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { action = "Login", controller = "Account" }));
}
}
全局过滤器:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new HandleAntiforgeryTokenErrorAttribute()
{ ExceptionType = typeof(HttpAntiForgeryException) }
);
}
}
我建议您使用一些工具来记录所有信息,因为登录是应用程序的重要部分。
通用记录和关键应用程序异常(包括Web异常)的电子邮件使用
NLog。
使用
Elmah来过滤和电子邮件Web异常。
此外,您可能还希望查看名为SafeForm的jQuery插件。链接:
Link
对于这个问题,我已经看到了很多争论,每个人的观点都有其合理的观点。我的看法是(来自
owasp.org):
跨站请求伪造(CSRF)是一种攻击,它迫使最终用户在他们“当前已验证”的Web应用程序上执行不需要的操作,CSRF攻击特别针对改变状态的请求,而不是数据窃取。防伪令牌是特定于“谁正在登录”的。因此,一旦您登录,然后返回,旧令牌将不再有效。
现在我也使用授权IP地址登录到我的许多应用程序,并在用户IP地址更改时使用2因素授权,因此,如果存在跨站请求伪造,用户将不匹配IP地址并请求2因素授权。几乎就像安全路由器的工作方式。但是,如果您想在登录页面上保持它,只要设置友好的错误页面,人们就不会生气,因为他们会看到他们做错了什么。