刷新用户访问令牌时身份验证 cookie 块的数量增加ASP.NET 核心 2.2 cookie 身份验证 上下文问题描述AJAX 请求的预期行为出了什么问题

问题描述

上下文

  • 此问题涉及 ASP.NET core 2.2 MVC Web 应用程序
  • 此应用程序是使用混合流的 OIDC 客户端
  • 我们使用另一个基于 IdentityServer4ASP.NET core 2.2 网络应用程序作为身份提供者
  • 客户端应用程序参考 IdentityModel.AspNetCore 版本 2.0.0 来管理用户访问令牌更新
  • 客户端 MVC 应用程序中的用户身份验证基于身份验证 cookie。 ASP.NET 核心会自动将我们的身份验证 cookie 分成块。 在所有客户和测试环境中,我们有 3 个身份验证 cookie:其中两个是实际块,第三个是跟踪有 2 个实际块的 cookie。据我所知,这是 ASP.NET 核心 cookie 中间件的标准行为。

问题描述

客户端 MVC 应用程序的一个页面对操作方法进行 AJAX 调用,其目的是确保用户访问令牌未过期。 此 AJAX 调用通过发送身份验证 cookie 和请求本身进行身份验证

这是被调用的动作方法的实现:

[ApiExplorerSettings(IgnoreApi = true)]
[Route("boapi/refreshAccesstoken")]
[Authorize]
public class RefreshAccesstokenController : NonCachableController
{
  [HttpPost("")]
  public async Task<IActionResult> RefreshAccesstoken()
  {
    await HttpContext.GetUserAccesstokenAsync();
    return Ok();
  }
}

如您所见,我们通过调用 GetUserAccessTokenAsync extension method

确保用户访问令牌未过期

AJAX 请求的预期行为

在我们所有的测试和客户环境中(但我正在写这个问题的那个环境)上述 AJAX 调用不会改变用户身份验证 cookie 的块数。我们已经配置了 Identity Server 4,以便用户访问令牌在一小时后过期。因此,如果用户登录并在一小时后执行 AJAX 请求,则用户访问令牌会在后端刷新,并且相应的 HTTP 响应会为用户设置新的 cookie。根据我的理解,用户访问令牌被序列化为身份验证 cookie 的一部分,因此每当用户访问令牌更改时,身份验证 cookie 本身也会更改。 This should be the code responsibile for setting the new authentication cookie in the HTTP response

这是从我们的一个测试环境中截取的屏幕截图:您可以注意到 HTTP 请求向后端端点发送了 3 个 cookie,并且相应的 HTTP 响应设置了完全相同的 3 个 cookie。这是标准和预期的行为。

enter image description here

出了什么问题

在我们的一个生产环境中,当执行所描述的 AJAX 调用时,我们观察到身份验证 cookie 的数量意外增长。请求 cookie 是 3,但响应中对应的 cookie 多得多(下面截图描述的情况是 7,但这似乎是随机的)。这种 cookie 数量的增长,当多次重复时,认证 cookie 的总数为 12 或 13:此时浏览器执行的所有 HTTP 请求都失败并返回 400 响应状态代码(reqeust饼干太大)。此时应用程序不再可用,用户需要关闭浏览器,重新打开并重新登录

这是从违规生产环境中截取的屏幕截图。如您所见,有 3 个请求 cookie 和 8 个响应 cookie。

enter image description here

你知道发生了什么吗?

我不明白为什么 ASP.NET 核心为身份验证 cookie 创建的块数在刷新用户访问令牌后会增加。这对我来说没有意义,因为用户身份没有改变:唯一认为改变的是用户访问令牌。

我错过了什么吗?

您是否知道此问题的可能根本原因?任何我可以调查的提示都将不胜感激。

请注意,我无法在其他环境中不断重现此问题,因此我将排除 IdentityServer.AspNetCore 库中的错误我很确定这个问题与这个生产环境的一些极端情况有关,但我不知道从哪里开始找到它。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)