IdentityServer4 访问令牌生命周期

Posted

技术标签:

【中文标题】IdentityServer4 访问令牌生命周期【英文标题】:IdentityServer4 Access Token Lifetime 【发布时间】:2018-10-26 01:40:03 【问题描述】:

我正在使用 IdentityServer4,它的配置在数据库中。客户端 (oidc) 有静默更新。我为客户端设置了以下生命周期设置:

AbsoluteRefreshTokenLifetime =  60 * 30,//30 mins
AccessTokenLifetime = 60 * 5,//5 mins
SlidingRefreshTokenLifetime = 60 * 15 // 15 mins

应该发生什么?令牌的生命周期应该是多长?什么时候应该要求用户再次登录?没有关于令牌生命周期何时刷新以及何时过期的明确文档。

【问题讨论】:

【参考方案1】:

访问令牌有两种形式 - 自包含或引用。

JWT 令牌将是一个独立的访问令牌 - 它是一个受保护的 带有声明和过期的数据结构。一旦 API 学会了 关于密钥材料,它可以验证自包含令牌,而无需 需要与发行人沟通。这使得 JWT 难以 撤销。它们将一直有效,直到过期。

来自http://docs.identityserver.io/en/latest/topics/reference_tokens.html#reference-tokens

刷新令牌允许长期访问 API。

您通常希望访问令牌的生命周期尽可能短 可能,但同时又不想打扰用户 再次进行到 IdentityServer 的前端通道往返 请求新的。

刷新令牌允许在没有用户的情况下请求新的访问令牌 相互作用。每次客户端刷新它需要制作的令牌时 对 IdentityServer 的(经过身份验证的)反向通道调用。这允许 检查刷新令牌是否仍然有效,或已被撤销 同时。

来自http://docs.identityserver.io/en/latest/topics/grant_types.html#refresh-tokens

所以访问令牌是自包含的,这意味着它不能被修改。一旦颁发,令牌将一直有效,直到过期。这就是为什么要使用短期令牌的原因。

为了使访问令牌更新过程自动化,您可以使用刷新令牌。这是一个强大的令牌,因为它可以用于请求访问令牌而无需用户交互。刷新令牌应该是长期存在的(至少比访问令牌长)。

刷新令牌过期后,用户必须重新登录。如果不滑动过期,刷新令牌将在绝对时间内过期,让用户再次登录。

通过滑动到期,您可以设置更短的刷新令牌生命周期。因为每次请求访问令牌时,都会发出一个新的刷新令牌。延长生命周期并使使用的刷新令牌失效。

只要刷新令牌有效,用户就可以访问资源而无需再次登录。在您的情况下,如果用户处于非活动状态超过 30 分钟,它就会过期。

访问令牌不会自动刷新。您需要在客户端中添加代码以请求新的访问令牌。如果刷新令牌不可用或过期,您可以将用户发送到登录页面。

【讨论】:

感谢@ruard-van-elburg 的精彩解释。但是,访问令牌不会在 30 分钟后过期。你觉得哪里不对? 根据您的配置,访问令牌应在 5 分钟后过期。你能确认一下吗? 访问令牌每 5 分钟刷新一次(automaticSilentRenew 设置为 true)。我正在检查,我看到我的前端客户端(角度 5)授权类型设置为“隐式” 我从 15:59:10.251 到 16:35 进行了测试。这里是静默刷新的调用时间:16:03:12.016, 16:07:13.119, 16:07:15.005 我为此客户端使用“隐式”授权类型,因此(根据文档)没有刷新令牌。我将 oidc 客户端的“automaticSilentRenew”设置为“true”。我有几个问题:自动更新授权令牌的时间是什么时候,以及到期时间是什么时候(之后将不再更新)?【参考方案2】:

据我了解,AbsoluteRefreshTokenLifetime 和 SlidingRefreshTokenLifetime 不适用于 oidc 客户端应设置的隐式流:

http://docs.identityserver.io/en/release/topics/refresh_tokens.html

由于访问令牌的生命周期有限,因此刷新令牌允许在无需用户交互的情况下请求新的访问令牌。

以下流支持刷新令牌:授权代码、混合和资源所有者密码凭证流。需要明确授权客户端通过将 AllowOfflineAccess 设置为 true 来请求刷新令牌

我遇到过类似的情况,为了测试,我将 cookie 设置为 15 分钟到期并带有滑动到期,并且根据下面的问题线程,如果使用静默续订,则必须手动处理:

https://github.com/IdentityModel/oidc-client-js/issues/402

我是 javascript 客户端的新手,所以我仍在尝试弄清楚您如何确定用户是否存在。我希望 cookie 会为我处理这个问题,但看起来它会随着我发送的线程不断扩展。

更新

经过测试和大量谷歌搜索后,我能够开始工作/了解访问令牌的生命周期和静默更新。

首先我假设您使用的是 oidc-client 或 redux-oidc。我正在使用 redux-oidc,它只是 oidc-client 的包装器。

由于您将访问令牌生命周期 (AccessTokenLifetime) 设置为 5 分钟,并且静默更新 = true。这将每 2.5 分钟更新一次,或者取决于您将 userManager.accessTokenExpiringNotificationTime 设置为什么。届时它将根据您的 cookie 过期超时设置来更新访问令牌。饼干是魔法发生的地方。如果 cookie 过期,您将无法再更新访问令牌。 cookie 设置如下:

Identity Server start.cs(这将设置 cookie 的滑动过期):

var builder = services.AddIdentityServer(options =>

   options.Authentication.CookieSlidingExpiration = true;
)

Identity Server AccountController.cs,登录方法(如果您有记住我的功能,您可以更改 IsPersistent 值,tsConfigValue = 15):

var props = new AuthenticationProperties

   IsPersistent = false,
   ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(tsConfigValue))
;

这最终解决了我的访问令牌生命周期和静默更新问题。希望对您有所帮助。

【讨论】:

以上是关于IdentityServer4 访问令牌生命周期的主要内容,如果未能解决你的问题,请参考以下文章

有人知道 Facebook API 访问令牌的生命周期吗?

访问和刷新令牌的生命周期

更改 Azure AD B2C 访问令牌生命周期不起作用

我正在使用 IdentityServer4,我正在尝试使用访问令牌访问同一服务器上的其他 API 端点,总是收到 401

如何在 Keycloak 中指定刷新令牌的生命周期

IdentityServer4 访问令牌更新