具有滑动到期的 IdentityServer 永远不会注销用户
Posted
技术标签:
【中文标题】具有滑动到期的 IdentityServer 永远不会注销用户【英文标题】:IdentityServer with Sliding Expiration Never Logs User Out 【发布时间】:2021-05-13 04:51:53 【问题描述】:我在 SO 上找到的大多数问题都有相反的问题 - 即会话没有滑动。我的问题是它似乎永远不会停止。
如果我将窗口设为绝对窗口 (SlidingExpiration = false
),我能够自动注销过期会话的唯一方法。
我正在使用 IdentityServer 4 和 ASP.NET Identity 作为后备用户存储。
我目前拥有的cookie的配置是:
services.AddIdentity<IdpUser, IdentityRole<int>>()
.AddEntityFrameworkStores<IdpDbContext>()
.AddDefaultTokenProviders();
// Note ASP.NET identity uses a cookie called "Identity.Application"
services.ConfigureApplicationCookie(options =>
options.ExpireTimeSpan = TimeSpan.FromMinutes(15); // for testing purposes
options.SlidingExpiration = true;
);
我们的客户端是一个 Vuejs 应用,使用 oidc-client.js 来管理令牌。
我已将客户端配置中的所有生命周期缩短到 300 秒(包括访问令牌)。因此,它每 300 秒获得一个新的 access_token。
我预计如果我登录后离开超过 15 分钟然后回来,我会被注销。但这种情况并非如此。它不断获得新的令牌。
即使我刷新整个页面,我仍然没有退出。
经过进一步调查,我相信oidc-client.js
所做的持续轮询正在扩展身份验证cookie 的滑动窗口。这是一个基于观察到的行为的理论。我增加了 access_token 生命周期的持续时间,使其比身份验证 cookie 更长。在这种情况下,用户在 auth cookie 过期后被注销。大概是因为客户端在那个时候没有请求另一个 access_token(从而延长了窗口)。
所以滑动窗口似乎会一直滑动直到达到SlidingRefreshTokenLifetime
,默认为15天左右。
将SlidingRefreshTokenLifetime
减少到大约 3 小时可能是我的答案吗?
谢谢
【问题讨论】:
可能不相关,但您应该始终为 cookie 设置一个特定于应用程序的名称(我认为是 options.Cookie.Name),这样您就不会拥有多个具有相同默认名称的不相关 cookie(Identity.Application )。 【参考方案1】:我的猜测是你在不知不觉中覆盖了它,因为它的文档记录很差,请仔细检查你是否使用Token Lifetime
,这样你就没有覆盖它。 SlidingExpiration 仅在您的 Cookie 中间件上。
要修复它,尝试设置UseTokenLifetime = false;
在客户端的 openIdOptions 和 IdentityServer 中间件的 CookieOptions 中仔细检查/设置它。
更新/回复评论:
@onefootwill,是的,请这些是 IdentityServer4 & Asp NET Core 2,3 & 5 的重要组成部分,请看下面的官方文档图片
身份服务器 4
微软
MSDN ref
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
...
UseTokenLifetime = false,
...
);
客户
对于 JWT,您是否使用访问刷新令牌设置了您的客户端,有两个确保您也配置了这些。刷新令牌
var idsClient = new Client
ClientName = configuredOption.Name,
ClientId = configuredOption.ClientId,
RequireConsent = false,
RequirePkce = false,
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true,
// Double check how you configure ** RefreshTokenUsage
// you can do one time or other options
RefreshTokenUsage = TokenUsage.OneTimeOnly,
RefreshTokenExpiration = TokenExpiration.Sliding,
AccessTokenLifetime = new TimeSpan(2,0,0).TotalSeconds,
//AccessTokenLifetime = 7200, //2 hours
AbsoluteRefreshTokenLifetime = xx, // set this up
SlidingRefreshTokenLifetime = yy // set this up
;
oidc-client-js
的更新 2 应该可以在您的 vue.js 中使用
开箱即用我不认为它在那里,但您可以在 不活动
一段时间后实现/让用户重新登录在您的 oidc-client-js 中配置 automaticSilentRenew to false
并设置您的 UserSsoLifetime
好 sample code/question and quick startUI from github
实现您自己的逻辑以指示用户不活动并调用SigninSilent API, sample code。在不活动后让用户过期/重新登录:
automaticSilentRenew = false
在Identity server configuration 中配置此UserSsoLifetime
“自上次用户身份验证以来的最大持续时间(以秒为单位)。...”
【讨论】:
我已经搜索了我的项目,但根本没有使用它。除此之外,我认为现代 API 中不再存在这种情况。我在任何选项对象中都找不到它。在我的 API 上,我使用了 AddJwtBearer 扩展,它在调用 services.AddAuthentication 后流畅使用。 @onefoots 将请参阅我附加的文档 - 现代 API 的非常重要的部分 请尝试添加/编码并配置它,这些配置对我有用.. 确保您硬删除缓存,如果它仍然无法正常工作,我们可以尝试其他方法 首先,我承认我错了,你提到的 API 不是最新的。否则,您会使用UseOpenIdConnectAuthentication
进行 SPA 吗?我的客户端应用程序是一个 Vuejs 应用程序,它通过 oidc-client.js
与 Idp 进行通信。因此,ASP.NET 项目只是一个 API。这就是我使用 AddJwtBear 的原因。没有 cookie 被发送到 API。 cookie 仅与 Vue.js 应用程序及其通过身份验证代码流与 IDP 的关系相关。
@onefootswill 知道了...在oidc-client.js
中尝试上面的小菜一碟,但希望它为您提供客户端令牌和示例代码以提供帮助。我将不得不清理我的答案:)
干杯。我将检查 UserSsoLifetime 属性。我必须确保这也适用于 AD 用户。有时用户将使用 ASP 的身份框架存储,有时他们将使用 LDAP 从本地 AD 中提取。以上是关于具有滑动到期的 IdentityServer 永远不会注销用户的主要内容,如果未能解决你的问题,请参考以下文章
IdentityModel 实施:如何在到期日或之后验证(和刷新)access_token?
在Application Insights中发现IdentityServer4错误
IdentityServer4具有没有UI的LDAP / AD身份验证