ASP.NET Core 8中如何根据登录用户设置Cookie与Session超时
问题描述
当前使用以下代码配置Cookie和Session超时(必须使用该API,无法切换到新Identity API):
.AddCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(15); options.SlidingExpiration = true; options.Cookie.MaxAge = options.ExpireTimeSpan; }) .AddOpenIdConnect(options => { options.MaxAge = TimeSpan.FromMinutes(15); ... });
该配置会给所有用户设置相同的超时时间,且参数值在重定向到IDP前就已固定。
需求:用户登录成功后(Cookie返回UI之前),根据Azure B2C返回的用户角色动态更新Cookie和Session的超时时间,询问实现方式及是否有可监听的事件来获取Azure返回信息并调整超时。
实现方案
可以通过监听OpenID Connect的OnTokenValidated事件来实现,这个事件会在IDP返回的令牌验证通过后触发,此时已经能获取到Azure B2C返回的用户角色信息,且还未生成并返回Cookie到前端。
具体实现步骤:
- 在
AddOpenIdConnect配置中注册OnTokenValidated事件 - 在事件处理逻辑中,从
context.Principal提取用户角色 - 根据角色设置对应超时时间,修改Cookie认证选项的
ExpireTimeSpan和Cookie.MaxAge,同步调整OpenID Connect的MaxAge(按需)
代码示例:
.AddCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(15); options.SlidingExpiration = true; options.Cookie.MaxAge = options.ExpireTimeSpan; }) .AddOpenIdConnect(options => { options.MaxAge = TimeSpan.FromMinutes(15); // 注册令牌验证完成事件 options.Events = new OpenIdConnectEvents { OnTokenValidated = context => { // 从用户身份信息中提取角色集合 var roles = context.Principal.Claims .Where(c => c.Type == ClaimTypes.Role) .Select(c => c.Value); // 根据角色设置不同超时时长 TimeSpan newExpireTimeSpan = roles.Contains("Admin") ? TimeSpan.FromMinutes(60) // 管理员设置60分钟超时 : TimeSpan.FromMinutes(15); // 普通用户保持默认15分钟 // 获取Cookie认证配置实例并更新超时参数 var cookieOptions = context.HttpContext.RequestServices .GetRequiredService<IOptionsMonitor<CookieAuthenticationOptions>>() .Get(CookieAuthenticationDefaults.AuthenticationScheme); cookieOptions.ExpireTimeSpan = newExpireTimeSpan; cookieOptions.Cookie.MaxAge = newExpireTimeSpan; // 同步更新OpenID Connect的MaxAge参数 options.MaxAge = newExpireTimeSpan; return Task.CompletedTask; } }; // 其他OpenID Connect配置项... });
关键说明
- 事件时机:
OnTokenValidated触发于令牌验证成功、Cookie生成之前,完全匹配你需要的调整时机 - 角色获取:Azure B2C返回的角色声明可通过
context.Principal.Claims获取,默认声明类型可使用ClaimTypes.Role常量引用 - 动态配置修改:通过
IOptionsMonitor<CookieAuthenticationOptions>获取配置实例,确保后续生成的Cookie直接应用新的超时设置
内容的提问来源于stack exchange,提问作者Matthew S
相关产品推荐
相关产品推荐

