IdentityServer4中令牌过期后自动生成新令牌的异常问题求助
你的问题核心在于IdentityServer4会复用Azure AD的未过期会话来重新获取身份凭证,进而生成新的Access/Refresh Token,而非依赖已过期的本地Refresh Token。以下是具体原因和解决办法:
核心原因
Azure AD会话Cookie未过期
用户登录时,Azure AD会在浏览器中设置会话Cookie(通常是ESTSAUTH),其默认有效期远长于你配置的1-2分钟Token时长(一般为20-30分钟,和你描述的循环周期吻合)。当本地Refresh Token过期后,IdentityServer向Azure AD发起身份请求时,Azure AD发现用户会话Cookie仍有效,会直接返回新凭证,无需用户重新登录。IdentityServer4本地会话未过期
IdentityServer自身会维护用户本地会话(存储在Redis的idsrv.session键中),若该会话有效期设为20-30分钟,即便本地Refresh Token过期,IdentityServer也会基于本地会话的用户信息,向Azure AD请求新凭证,生成新Token。
解决办法
1. 缩短Azure AD会话有效期
登录Azure Portal,找到对应应用注册/企业应用:
- 进入令牌配置,设置会话令牌生存期为目标时长(比如2分钟)
- 进入会话配置,设置最大会话持续时间为匹配值,并开启用户注销时撤销所有会话Cookie
2. 调整IdentityServer4本地会话配置
在Startup.cs的身份认证配置中,明确设置会话Cookie的过期时间,与Token有效期对齐:
services.AddAuthentication() .AddCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(2); // 和Refresh Token有效期一致 options.SlidingExpiration = false; // 禁止滑动过期,确保到点强制注销 });
3. 控制IdentityServer与Azure AD的交互逻辑
在Azure AD的OpenIdConnect配置中,添加事件监听,强制会话过期后重新验证:
services.AddAuthentication() .AddOpenIdConnect("AzureAD", options => { // 其他原有配置... options.Events = new OpenIdConnectEvents { OnRefreshTokenReceived = context => { // 检查本地会话有效性,无效则跳转登录页 if (!context.HttpContext.User.Identity.IsAuthenticated) { context.Response.Redirect("/Account/Login"); context.HandleResponse(); } return Task.CompletedTask; } }; });
4. 验证Redis会话缓存
直接查看Redis中idsrv.session相关键的过期时间,确认是否与观察到的20-30分钟一致,若不符,检查IdentityServer的Redis缓存配置是否正确设置了会话过期参数。
内容的提问来源于stack exchange,提问作者Sandeep Manchukonda

