我有一个ASP .NET Core 3.1后端,其前端为angular 9(基于dotnet angular tenplate,刚刚将其更新为v9)。我使用cookie身份验证(我知道JWT更适合SPA,将其作为实验),并且还在服务器端添加了对CSRF保护的支持:
services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN"; // angular csrf header name
});
我具有服务器端设置,可以使用以下方法自动检查CSRF:>
options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute())
因此未针对CSRF检查GET请求,但针对POST进行了检查。
在开始时,角度应用程序向api/init
发出GET请求,以在引导之前获取一些初始数据。在服务器端contoler动作中,按如下方式初始化CSRF
// init action body var tokens = _antiForgery.GetAndStoreTokens(HttpContext); Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false }); // return some inital data DTO
[这按预期工作,获取响应包含2个CSRF cookie-第一个是asp.net核心dafault CSRF cookie
.AspNetCore.Antiforgery...
,第二个是XSRF-TOKEN
,它将被angular读取并放入X-XSRF-TOKEN
标头中以用于后续请求。
[如果之后我从角度应用程序登录(包含api/auth/login
的凭据的POST请求,则所有工作-包括X-XSRF-TOKEN
标头和CSRF验证都通过了POST,因此,如果凭据正确,则用户登录。
现在是问题开始的地方。 ASP .NET服务器应用程序使用无身份验证的cookie身份验证,如此处https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1所述。在登录操作中,还需要重新生成CSRF令牌,就像通过身份验证一样,CSRF令牌是基于经过身份验证的用户身份生成的。因此,我的登录操作如下所示:
public async Task<IActionResult> Login(CredentialsDto credentials) { // fake user credentials check if (credentials.Login != "admin" || credentials.Password != "admin") { return Unauthorized(); } var claimsIdentity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "theAdmin"), }, CookieAuthenticationDefaults.AuthenticationScheme); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); await HttpContext.SignInAsync(claimsPrincipal); // refresh antiforgery token on login, same code as in init action before var tokens = _antiForgery.GetAndStoreTokens(HttpContext); Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false }); return new JsonResult(new UserDto { Id = 1, Login = "theAdmin" }); }
此爱好者无效。响应包含
XSRF-TOKEN
cookie(具有新值),但是后续POST请求(在我的情况下,其注销-POST到api/auth/logout
)失败,并显示400,尽管已正确地将此新值放入X-XSRF-TOKEN
标头中。我认为原因是由于某种原因未在响应中设置dafault.AspNetCore.Antiforgery...
cookie,因此即使登录后也保留了原始值,因此CSRF检查失败,因为值不匹配。
在这种情况下,如何正确刷新CSRF?
我有一个ASP .NET Core 3.1后端,其前端为angular 9(基于dotnet angular tenplate,刚刚将其更新为v9)。我使用cookie身份验证(我知道JWT更适合SPA,请使用此...
[经过更多的试验和错误,并且还搜索了asp.net github并找到了https://github.com/dotnet/aspnetcore/issues/2783和https://github.com/aspnet/Antiforgery/issues/155,似乎我想实现的目标在单个请求中是行不通的,因为在此期间用户的身份不会改变单个请求处理。