我们有一个带有Cookie身份验证的Angular SPA的ASP.NET Core 2.2 Web应用程序。
我正在按照configure antiforgery features with IAntiforgery的说明进行操作。
相关代码段为:
services.AddAntiforgery();
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
// The request token can be sent as a JavaScript-readable cookie,
// and Angular uses it by default.
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
对antiforgery.GetAndStoreTokens(context)
的调用返回一个AntiforgeryTokenSet
,它具有RequestToken
和CookieToken
属性。
如果我在默认配置下使用上述代码,则会得到两个cookie:.AspNetCore.Antiforgery.*
(匹配CookieToken
)和XSRF-TOKEN
(匹配RequestToken
),它们的值不同
RequestToken
和CookieToken
之间的用法有什么区别
答案 0 :(得分:1)
XSRF-TOKEN
:
这是Angular应用程序将读取并作为HTTP标头发送回的JavaScript可读cookie。
.AspNetCore.Antiforgery.*
:
这是仅用于HTTP的cookie(即 JavaScript可读),将由浏览器作为典型的cookie发送回服务器。
ASP.NET Core中的CSRF保护要求同时发送HTTP标头和cookie。验证请求时,它将同时检查标头和cookie。如果缺少任何一个,验证将失败。
答案 1 :(得分:1)
有两个cookie的原因是ASP.NET Core使用Double Submit Cookie中所述的OWASP Cross-Site Request Forgery (CSRF) Cheat Sheet模式。
这篇出色的文章ASP.NET Core CSRF defence with Antiforgery比Microsoft documentation更详细地描述了该过程:
...它提供了一种无状态防御机制,该机制由2个项目(或令牌集)组成,应在Antiforgery软件包验证的任何请求中找到:
包含在cookie中的防伪令牌,作为伪随机值生成并使用新的Data Protection API加密
包含为表单字段,标题或cookie的附加令牌。其中包括相同的伪随机值,以及来自当前用户身份的其他数据。还可以使用Data Protection API对其进行加密。
这些令牌将在服务器端生成,并与html文档一起传播到用户的浏览器。当浏览器发送新请求时,默认情况下将包含cookie令牌,而应用程序需要确保也包含该请求令牌。 (我们将在下一部分中看到如何执行此操作)
在以下情况下,请求将被拒绝
:
- 两个令牌中的任何一个都不存在或格式/加密不正确
- 它们的伪随机值不同
- 第二个令牌中嵌入的用户数据与当前经过身份验证的用户不符
对于Angular,您将使用其$ http服务发送AJAX请求。如果此服务可以找到标记值为XSRF-TOKEN的cookie作为令牌,则该服务将自动包含名称为X-XSRF-TOKEN的标头。因此,最简单的方法是按照Angular希望我们的方式进行操作,并创建一些将获取请求令牌的中间件,并将其值存储为XSRF-TOKEN cookie。
即使将其添加为cookie,它仍然是请求令牌,而不是cookie令牌!这听起来可能令人困惑,所以让我尝试澄清一下:
应用程序会将带有请求令牌的cookie XSRF-TOKEN和带有cookie令牌的另一个cookie .AspNetCore.Antiforgery。*发送回浏览器。 每当Angular发送Ajax请求时,请求将包括带有请求令牌的标头X-XSRF-TOKEN和带有cookie令牌的cookie .AspNetCore.Antiforgery。*。 防伪验证将确保两个令牌均有效并且共享相同的机密信息,等等。
因此应该有两个cookie。在我的场景中,随每个请求发送的.AspNetCore.Antiforgery.*
cookie构成了令牌集的一半,然后Angular使用XSRF-TOKEN
来设置X-XSRF-TOKEN
头,令牌集的另一半。
另请参阅: