ASP.NET Core MVC 8.0中OpenID Connect Cookie过期时长被忽略问题
我们有一个ASP.NET Core MVC 8.0 Web应用,通过Okta使用OpenID Connect认证,Okta侧已配置策略要求用户每24小时重新登录。此前为避免用户填写长表单时超时丢失数据,我们将Cookie过期时长设为120分钟,覆盖了默认1小时的会话过期,防止无活动1小时后触发静默认证。但自从更新NuGet上的OpenID Connect最新版本(此前版本滞后)后,该设置失效。
相关代码片段:
builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(options => { options.AccessDeniedPath = "/Home/NotAuthorized"; //redirect to custom not authorized view //options.Cookie.IsEssential = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(120); options.Cookie.MaxAge = TimeSpan.FromMinutes(120); options.SlidingExpiration = true; options.Cookie.HttpOnly = true; // not accessible via JavaScript //options.Cookie.Name = "OktaAuth2"; //make cookie persist otherwise you need to enter credentials every time options.Events.OnSigningIn = ctx => { ctx.Properties.IsPersistent = true; // ctx.Properties.AllowRefresh = true; ctx.Properties.ExpiresUtc = DateTime.UtcNow.AddMinutes(120); return Task.CompletedTask; }; }) .AddOpenIdConnect(options => { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.Authority = OpenIDConnectAuthority; options.UseTokenLifetime = false; options.ClientId = OpenIDConnectClientID; options.ClientSecret = OpenIDConnectSecret; options.ResponseType = OpenIdConnectResponseType.CodeIdToken; options.GetClaimsFromUserInfoEndpoint = true; options.SaveTokens = true; options.Scope.Add("openid"); options.Scope.Add("profile"); // options.Scope.Add("groups"); //uncomment this to use groups brought over from identity provider for role checking User.IsInRole() options.Scope.Add("email"); options.SignedOutRedirectUri = OpenIDConnectRedirectURL; options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "preferred_username", // RoleClaimType = "groups" //uncomment this to use groups brought over from identity provider for role checking User.IsInRole() }; options.TokenValidationParameters.ValidateIssuer = true; });
我们已尝试注释/取消注释Stack Overflow上建议的各类参数(如移除Cookie名称),也添加了SigningIn事件代码,但均无效果。此前功能正常,且确认Okta侧未做相关更改,求解决思路。
强制在Token验证阶段覆盖会话过期:
虽然设置了UseTokenLifetime = false,但新版本OIDC包可能对该参数的处理逻辑有调整。可以在AddOpenIdConnect的OnTokenValidated事件中手动设置会话过期时间,确保Cookie的过期时间不受ID Token生命周期影响:options.Events.OnTokenValidated = ctx => { ctx.Properties.ExpiresUtc = DateTime.UtcNow.AddMinutes(120); ctx.Properties.IsPersistent = true; return Task.CompletedTask; };检查Cookie配置的加载顺序与冲突:
新版本可能调整了认证中间件的配置加载优先级,尝试将AddCookie的配置移到AddOpenIdConnect之后,或者确保SignInScheme的配置没有被OIDC的默认值覆盖。同时排查是否有其他中间件(如Session中间件)修改了Cookie的生命周期设置。验证浏览器中Cookie的实际属性:
用浏览器开发者工具(Application面板 -> Cookies)查看生成的认证Cookie的Expires/Max-Age值,确认是否为120分钟。如果不是,说明配置未生效,需检查是否有其他代码(如自定义的OnRedirectToLogin事件)覆盖了过期时间。排查NuGet版本变更的具体影响:
对比更新前后的Microsoft.AspNetCore.Authentication.OpenIdConnect包版本,查看官方Release Notes或文档,确认是否有关于会话生命周期、Cookie配置的变更。部分版本可能加强了Token生命周期校验,即使设置UseTokenLifetime=false也需额外配置。调整SlidingExpiration与Cookie参数的配合:
当IsPersistent=true时,Cookie.MaxAge的优先级高于ExpireTimeSpan,可能导致设置冲突。尝试暂时注释Cookie.MaxAge,只保留ExpireTimeSpan和SlidingExpiration,看是否生效:// options.Cookie.MaxAge = TimeSpan.FromMinutes(120); options.ExpireTimeSpan = TimeSpan.FromMinutes(120); options.SlidingExpiration = true;
内容的提问来源于stack exchange,提问作者PlasmaX

