答案很可能与性能有关。
OAuth2 访问令牌被设计为短暂的,而刷新令牌被设计为更长寿,因为它们可用于获取新的访问令牌。大多数客户端库旨在缓存 OAuth 访问令牌以避免访问授权服务器。看这里:
https://github.com/google/google-api-dotnet-client/blob/master/Src/Support/GoogleApis.Auth/OAuth2/UserCredential.cs
/// <summary>
/// Default implementation is to try to refresh the access token if there is no access token or if we are 1
/// minute away from expiration. If token server is unavailable, it will try to use the access token even if
/// has expired. If successful, it will call <see cref="IAccessMethod.Intercept"/>.
/// </summary>
public async Task InterceptAsync(HttpRequestMessage request, CancellationToken taskCancellationToken)
[...]
如果您访问 Google OAuth2 游乐场,您可以看到其中的一些实际操作:
https ://developers.google.com/oauthplayground/
当您授权 API 时(只需尝试在自定义范围中键入“配置文件”并单击“授权 API”,如果您不想单击列表),在进行身份验证交换并接收访问/刷新令牌之后,您将看到以下内容:
“访问令牌将在 [countdown] 秒后过期。
[ ] 在令牌过期之前自动刷新令牌。”
通过缓存或存储访问令牌,您可以避免往返授权服务器以将刷新令牌交换为访问令牌(防止延迟和授权服务器中断)。某些服务器还可能会限制您将刷新令牌交换为访问令牌的频率(例如,生成访问令牌可能涉及它们的“昂贵”加密操作)。
泄漏访问令牌是“不好的”,因为它可以在没有任何其他信息的情况下使用,以断言授予它的人的身份 - 但由于访问令牌的寿命有限,增加了压力攻击者立即提示/使用这些值。泄漏刷新令牌(理论上)“更糟”,因为它允许永久访问,但是使这更复杂的是,进行刷新 <-> 访问令牌交换还需要了解您的 OAuth2 client_secret。
在您描述的当前模型中,尚不清楚 ProtectedTicket 是否已加密(您提到它是序列化的,但稍后会谈到更新持久票证)。如果您正在加密数据库中的访问令牌以保护它们不被具有管理数据库访问权限的人(误用),您可以查看处理版本化密钥的解决方案,这将允许您轮换加密密钥。我熟悉的一个是https://github.com/google/keyczar,有人为此创建了 .NET 绑定(我从您的屏幕截图中假设您在 .NET 上)。
KeyCzar 可能会提供一种简单的方法来解决您的一些问题,但是您系统的许多实际安全属性将取决于您的威胁模型和数据库架构之外的许多因素。