AntiforgeryToken验证失败

时间:2018-07-20 12:37:47

标签: authentication antiforgerytoken asp.net-core-2.1

我有ASP CORE 2.1应用程序,可与angular SPA客户端一起使用。 我按照here的说明保护了我的应用。

但是问题是,登录系统后,我不断收到400错误请求。根据我的观点,这就是系统中发生的事情:

  1. 对应用程序的第一个请求->返回AntiForgery CookieToken和 RequestToken(重要说明,该用户尚未通过身份验证
  2. 用户登录到系统->通过了防伪验证, 发送给客户端的身份验证Cookie。
  3. 用户请求任何 其他端点,但是因为AntiforgeryTokenSet是针对 未经身份验证的用户,他会收到400错误请求。

很明显,登录后我们需要重新发行AntiforgeryTokenSet,但是我不知道在哪里以及如何进行。我试图在结果过滤器中发行令牌,但是没有运气。

public class SPAAntiforgeryCookieResultFilter : ResultFilterAttribute
    {
        private readonly IAntiforgery _antiforgery;

        public SPAAntiforgeryCookieResultFilter(IAntiforgery antiforgery)
        {
            _antiforgery = antiforgery;
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Action assignAntiForgery = () =>
            {
                var tokens = _antiforgery.GetAndStoreTokens(context.HttpContext);
                context.HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
            };

            if (context.Result is ViewResult)
            {
                assignAntiForgery();
            }
            else if (string.Equals(context.ActionDescriptor.ActionName, nameof(AccountController.Login), StringComparison.OrdinalIgnoreCase))
            {
                assignAntiForgery();
            }
        }
    }

似乎ResultExecutingContext不了解经过身份验证的用户,并且仍为匿名用户颁发令牌。 那么,如何在身份验证用户登录后立即刷新防伪RequestToken令牌?

1 个答案:

答案 0 :(得分:0)

现在,我找到了解决该问题的方法。

以前,我成功登录后返回了Ok(),但是现在我做了RedirectToAction(),并且对OnResultExecuting过滤器进行了些微更改,以便在发生RedirectToAction之后刷新令牌。 / p>

    public class SPAAntiforgeryCookieResultFilter : ResultFilterAttribute
        {
            private readonly IAntiforgery _antiforgery;

            public SPAAntiforgeryCookieResultFilter(IAntiforgery antiforgery)
            {
                _antiforgery = antiforgery;
            }

            public override void OnResultExecuting(ResultExecutingContext context)
            {
                Action assignAntiForgery = () =>
                {
                    var tokens = _antiforgery.GetAndStoreTokens(context.HttpContext);
                    context.HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
                };

                if (context.Result is ViewResult)
                {
                    assignAntiForgery();
                }
                // Here we check whether our redirect action is executed. Update AFT if it is
                else if (string.Equals(context.ActionDescriptor.RouteValues["action"], nameof(AccountController.RefreshAntiForgeryAfterLogin), StringComparison.OrdinalIgnoreCase))
                {
                    assignAntiForgery();
                }
            }
        }

这种肮脏的骇客具有以下作用:

  1. 对应用程序的首次请求->返回AntiForgery CookieToken和RequestToken(重要说明,该用户尚未通过身份验证)
  2. 用户按登录名进入系统->通过了防伪验证,设置了身份验证cookie->用户获得带有身份验证cookie和状态代码302(重定向)的响应->用户使用来访问我们的RedirectUserToAction方法具有身份验证信息的上下文User.IsAuthenticated == true