authentication - AntiforgeryToken 验证失败
问题描述
我有 ASP CORE 2.1 应用程序,它与 Angular SPA 客户端一起工作。我按照此处所述保护了我的应用程序。
但问题是我在登录系统后经常收到 400 Bad Request。根据我的观点,这就是系统中发生的事情:
- 对应用程序的第一个请求 -> 返回 AntiForgery CookieToken 和 RequestToken (重要说明用户尚未通过身份验证)
- 用户登录系统 -> AntiForgery 验证通过,身份验证 cookie 发送到客户端。
- 用户请求任何其他端点,但由于 AntiforgeryTokenSet 是为未经身份验证的用户发出的,因此他收到 400 Bad Request。
很明显,登录后我们需要重新发布 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 令牌?
解决方案
现在我找到了解决这个问题的方法。
以前,我Ok()
在成功登录后返回,但现在我这样做RedirectToAction()
了,我的OnResultExecuting
过滤器略有改变,以便在发生后刷新令牌RedirectToAction
。
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();
}
}
}
这种肮脏的技巧以以下方式起作用:
- 对应用程序的第一个请求 -> 返回 AntiForgery CookieToken 和 RequestToken(重要的是,用户尚未经过身份验证)
- 用户按登录到系统 -> AntiForgery 验证通过,身份验证 cookie 设置 -> 用户使用身份验证 cookie 和状态码 302(重定向)获得响应 -> 用户使用具有身份验证信息的上下文()联系我们的
RedirectUserToAction
方法User.IsAuthenticated == true
推荐阅读
- c++ - 无法在动态库中找到过程入口点 _gxx_personality_vo
- c# - ValueTuple.Create 中的命名参数
- javascript - 如何在 cmd 中使用运算符“<”将 .txt 文件“发送”到 javascript 文件
- javascript - 如果导入了 events-polyfill,React Datepicker 将无法正常工作
- azure - Azure 从 Internet 访问 ILB
- javascript - 如何在 html 表中从控制台更改显示 json 的类型
- html - css 伪元素 ::selection 无法正常工作
- angular - Angular 2:监听指令内父元素的滚动事件
- javascript - 模板JS | 在组件中导入第三方脚本
- java - java计算字符串中的二元组数