使用ASP.NET Core Web API中没有身份的cookie身份验证时,如何在登录时刷新CSRF令牌

问题描述 投票:0回答:1

我有一个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,请使用此...

angular asp.net-core authentication asp.net-web-api csrf
1个回答
0
投票

[经过更多的试验和错误,并且还搜索了asp.net github并找到了https://github.com/dotnet/aspnetcore/issues/2783https://github.com/aspnet/Antiforgery/issues/155,似乎我想实现的目标在单个请求中是行不通的,因为在此期间用户的身份不会改变单个请求处理。

© www.soinside.com 2019 - 2024. All rights reserved.