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 访问令牌生命周期的主要内容,如果未能解决你的问题,请参考以下文章
我正在使用 IdentityServer4,我正在尝试使用访问令牌访问同一服务器上的其他 API 端点,总是收到 401