Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 登录页面上的防伪令牌_C#_Asp.net Mvc 3_Antiforgerytoken - Fatal编程技术网

C# 登录页面上的防伪令牌

C# 登录页面上的防伪令牌,c#,asp.net-mvc-3,antiforgerytoken,C#,Asp.net Mvc 3,Antiforgerytoken,我已经在我的登录页面上实现了反伪造令牌 现在有一个用户按下键盘上的后退键, 当他们填写完凭证后再次点击登录按钮时,他们会看到错误页面 有没有更好的方法来处理这个案子,比如把他们转移到 新的登录页面 作为登录页面的页面是:/account/logon 如果登录详细信息成功,用户将重定向到:主页/索引页 用户在其上按下后退按钮。不要在登录页上实现ASP.NET AntiForgeryToken。令牌基于用户名和其他标准,登录页面假设攻击者已经拥有系统凭据,以便能够利用该页面上的csrf 但是,您应该

我已经在我的登录页面上实现了反伪造令牌

现在有一个用户按下键盘上的后退键, 当他们填写完凭证后再次点击登录按钮时,他们会看到错误页面

有没有更好的方法来处理这个案子,比如把他们转移到 新的登录页面

作为登录页面的页面是:/account/logon

如果登录详细信息成功,用户将重定向到:主页/索引页
用户在其上按下后退按钮。

不要在登录页上实现ASP.NET AntiForgeryToken。令牌基于用户名和其他标准,登录页面假设攻击者已经拥有系统凭据,以便能够利用该页面上的csrf


但是,您应该在登录页面上使用某种形式的CSRF保护-请参阅我的解决方案是:

如果再次点击登录页面,请重新加载页面。 这将确保新装载的防伪代币


一切都完成了

我在这里写了一个完整的解决方案:

以下是在控制器窗体中调用GET方法所需的代码:

private void SetANewRequestVerificationTokenManuallyInCookieAndOnTheForm()
{
    if (Response == null)
        return;

    string cookieToken, formToken;
    AntiForgery.GetTokens(null, out cookieToken, out formToken); 
    SetCookie("__RequestVerificationToken", cookieToken);
    ViewBag.FormToken = formToken;
}

private void SetCookie(string name, string value)
{
   if (Response.Cookies.AllKeys.Contains(name))
       Response.Cookies[name].Value = value;
   else
       Response.Cookies.Add(new HttpCookie(name, value));
}
和代码放置在视图中以代替Html.AntiForgeryToken():

@if(ViewBag.FormToken!=null)
{
}
其他的
{
@Html.AntiForgeryToken()
}

与前面提到的其他帖子一样,我没有检查User.Identity.IsAuthenticated,而是使用自定义属性来处理异常,并将用户重定向到主页(如果是httpantiforyToken)

我相信这避免了使用其他方法的任何潜在安全问题,并且[ValidateAntiForgeryToken]应该始终用于POST方法

public override void OnException(ExceptionContext filterContext)
    {
        var controllerName = (string)filterContext.RouteData.Values["controller"];
        var actionName = (string)filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
        if (filterContext.Exception is HttpAntiForgeryException)
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary
                {
                    { "action", "Index" },
                    { "controller", "Home" }
                });

            filterContext.ExceptionHandled = true;
        }
}

当用户按下backspace时,他在哪一页?@DarinDimitrov:请参阅我的updateCSRF函数“通常”通过已验证的用户代理请求,以代表该用户执行某些操作。如果攻击者正在攻击登录页面,则表示他们已经拥有凭据。在这种情况下,他们可以自己登录。如果它是一个内部应用程序,并且他们从外部代理,那么他们可以等待用户登录。如果你想在这里使用一个令牌,你必须破解现有的方法并想出一些新的东西。反伪造令牌特定于“谁已登录”。所以,一旦你登录,然后返回,旧令牌不再有效,这就是你的问题。我对@AdamTuliper的回复很有信心,直到我偶然发现了这一点——这篇文章有一个参考资料——这是一本很好的读物。我应该在我的答案前面加上“在asp.net mvcs中实现防伪令牌”,因为它基于登录名。来自匿名用户的令牌可能无法提供所需的保护-如果我记得的话,我必须在大多数情况下测试它与登录名的关联性。危险-不要这样做@aix是正确的,此答案引入了一个安全漏洞,其中CSRF请求可用于针对攻击者控制的凭据强制登录。然后,攻击者可以使用相同的帐户查看用户在站点上的活动。请参阅并请考虑删除或编辑此答案,因为这是非常危险的建议。因此,如果我们不应该在登录页面上使用ASP.NET反FooGyType,并且需要CSRF保护的形式,那么什么是更好的替代方案?我的意思是有一个好的图书馆或者你推荐的东西吗?我也用同样的方法。为此,我确保缓存头设置正确:(缓存控制=无缓存,无存储,必须重新验证),(过期=-1)。考虑到antiforgery令牌是“动态”的,这取决于用户上下文,除了在所有应用程序页面上设置不缓存(叹气)之外,它没有留下太多选择,对吗?我的意思是,用户可以登录,然后潜在地单击返回到他们以前所在的任意应用程序页面…如果该页面被缓存,并且他们尝试从中发布,那么他们将遇到错误。在我看来,对整个web应用程序没有缓存是唯一的解决方案:(注意:“不要实现伪造令牌”的投票结果不包括用户登录然后导航回其他应用程序(非登录)的情况)有伪造令牌的应用程序页面。谢谢,此解决方案为我解决了Qualys 150129会话保护/再生不足漏洞。更新链接:Thank you@Manoj。我将我的博客从Wordpress切换到Hexo,现在也更新了我答案中的链接。谢谢@Richard。你的解决方案帮助我解决了问题ve“登录后会话标识符未更改”安全问题。如果filterContext的类型为,则受保护会覆盖Sub-OneException(filterContext作为ExceptionContext)。异常为HttpAntiforyException,然后Dim结果=新建RouteValueDictionary()filterContext.result=重定向到操作(“登录”,“帐户”)filterContext.ExceptionHandled=如果结束子项,则为真结束
public override void OnException(ExceptionContext filterContext)
    {
        var controllerName = (string)filterContext.RouteData.Values["controller"];
        var actionName = (string)filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
        if (filterContext.Exception is HttpAntiForgeryException)
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary
                {
                    { "action", "Index" },
                    { "controller", "Home" }
                });

            filterContext.ExceptionHandled = true;
        }
}