【问题标题】:Token Sharing between multiple concurrent requests C#多个并发请求之间的令牌共享 C#
【发布时间】:2021-06-27 14:19:41
【问题描述】:

我有一个应用程序 (A),多个用户可以通过该应用程序登录。用户名和密码,并接收即将到来的请求的令牌。如果他们的令牌过期,他们可以得到一个新的。这一切都很好。现在的问题是有时App(A)需要通过App(B)访问。一个 API 调用本身也需要一个(单独的)令牌。无论是哪个客户端进行调用,从 A 到 B 的调用都需要使用相同的令牌。换句话说 - 应用 B 不需要知道是哪个客户端发起呼叫,它只是将每个呼叫都视为来自应用 A。

我的问题在于以线程安全的方式生成和刷新 TokenB。假设 TokenB 已过期,C1、C2、C3 都在同一时间拨打电话。当然应该只生成一个新的令牌。

我认为这是一个很常见的障碍,但我真的找不到关于线程安全令牌(重新)生成这个特定主题的任何指南。

App A 是用 C# 编写的。并不是说它对这个问题很重要,但也许微软对此有解决方案。

【问题讨论】:

  • 这篇文章经过深思熟虑,目的明确。没有理由关闭它,因为“需要更多关注”

标签: c# security concurrency access-token


【解决方案1】:

好问题,在 OAuth 客户端中处理令牌刷新很棘手。有两种常见的技术。我更喜欢其中的第二种,因为它更可靠,但它需要更复杂的代码:

  • 应用 A 在后台计时器线程上定期刷新 TokenB,以防止出现 401
  • 应用 A 处理 401,通过令牌刷新然后重试对应用 B 的请求

同步令牌刷新

一种常见的技术是让客户端代码从外部看起来很简单:

var data = await myApiClient.getData();

但是在实现中的某个地方,当需要刷新令牌时,您会使用一组回调。其中第一个进行实际的刷新调用,当它完成时,它会以相同的结果解析所有其他回调。

示例代码

这是一些处理并发进行中令牌刷新的 TypeScript 代码。在 C# 中,您可以对任务执行等效的操作,并且您的回调处理需要是线程安全的:

【讨论】:

  • Gary 我认为这很聪明,感谢您的输入和示例!我想知道是否可以为令牌到期设置阈值(5 分钟),并且每次 A 尝试调用 B 时,它都会检查令牌是否还剩不到 5 分钟。如果是这样,将生成一个新令牌(线程安全以避免多次创建)并应用于即将到来的调用,但旧令牌对于当前客户端调用仍然有效。这当然要求允许多个并行令牌(它在 B 中)并且当前调用在不到 5 分钟内完成(它们总是这样做)。
  • 这是合理且常见的解决方案。唯一需要注意的是,即使令牌有效且未过期,对 App B 的调用也会导致 401。如果例如更新令牌签名证书或存在负载平衡开关,则在某些设置中可能会发生这种情况。这可能与您的情况无关,但值得确保没有应用 A 无法恢复的情况。
  • 嗨,Gary,好吧,这听起来像是当时的方法。您能否详细说明一下负载平衡开关如何导致多个有效令牌出现 401?我不确定我是否跟随。
  • 在某些设置中,例如,我在美国、欧洲、亚太地区看到了授权服务器的独立实例。如果不相关,请忽略。
  • 我认为这很有趣的原因是我有一个同事调用应用程序 B(在不同的上下文中,但也使用来自同一用户的多个令牌),有时(很少)它会给出 401对于其中一个线程,即使它之后仍然有效。这就是为什么我有点好奇你是否看过任何关于这个令牌 401“不稳定”的页面或文章。您也许可以想象,当我们上周在非常相似的事情上撞到办公室的墙上时,我很惊讶您提出了这个确切的问题!无论如何,非常感谢您的帮助。
猜你喜欢
  • 2020-01-09
  • 2017-05-27
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多