ASP.NET Core Azure AD中SSO时OnTokenValidated等事件未触发的解决咨询
解决ASP.NET Core Azure AD SSO静默登录时OnTokenValidated事件不触发的问题
问题原因
SSO静默登录时,ASP.NET Core会直接复用本地已缓存的身份认证Cookie,不会重新发起完整的OpenID Connect授权流程,因此OpenIdConnectEvents下的事件(包括OnTokenValidated)都不会被触发。只有当Cookie过期或被清除时,才会重新走OIDC流程触发这些事件。
解决方案
要覆盖首次登录和SSO静默登录两种场景,需要结合CookieAuthenticationEvents的OnValidatePrincipal事件——这个事件会在每次验证Cookie身份票据时触发,无论是否是SSO登录。
步骤1:提取复用的自定义逻辑
把原来OnTokenValidated中的自定义逻辑抽成独立方法,方便在多个事件中复用:
private async Task ApplyCustomUserLogic(ClaimsPrincipal principal) { Console.WriteLine($"Processing user: {principal.Identity.Name}"); var identity = (ClaimsIdentity)principal.Identity; // 避免重复添加自定义Claim if (!identity.HasClaim(c => c.Type == "CustomClaim")) { identity.AddClaim(new Claim("CustomClaim", "CustomValue")); } // 其他自定义逻辑,比如从数据库加载用户权限等 // var userPermissions = await _permissionService.GetPermissions(principal.Identity.Name); // foreach (var perm in userPermissions) // { // identity.AddClaim(new Claim(ClaimTypes.Role, perm)); // } }
步骤2:配置CookieAuthenticationEvents
在Cookie认证配置中添加OnValidatePrincipal事件,确保SSO场景触发逻辑:
builder.Services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, options => { options.Events = new CookieAuthenticationEvents { OnValidatePrincipal = async context => { await ApplyCustomUserLogic(context.Principal); // 如果需要更新Cookie中的票据(比如新增了Claim),启用以下代码 // context.ReplacePrincipal(context.Principal); // context.ShouldRenew = true; // 标记需要刷新Cookie } }; });
步骤3:更新OpenIdConnectEvents配置
保持原有的OnTokenValidated事件,同样调用复用的逻辑,覆盖首次登录场景:
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options => { options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = context => { Console.WriteLine("Redirecting to Azure AD..."); return Task.CompletedTask; }, OnTokenValidated = async context => { await ApplyCustomUserLogic(context.Principal); return Task.CompletedTask; }, OnAuthenticationFailed = context => { Console.WriteLine($"Authentication failed: {context.Exception.Message}"); context.Response.Redirect("/Error"); context.HandleResponse(); return Task.CompletedTask; }, OnAuthorizationCodeReceived = context => { Console.WriteLine("Authorization code received."); return Task.CompletedTask; } }; });
关键说明
OnValidatePrincipal会在每个请求验证Cookie时触发,完美覆盖SSO静默登录后的所有请求。- 抽离复用逻辑可以避免代码冗余,保证首次登录和SSO场景的逻辑一致性。
- 如果修改了
ClaimsPrincipal(比如添加新Claim),需要调用context.ReplacePrincipal并设置ShouldRenew = true,否则修改不会被持久化到Cookie中。
内容的提问来源于stack exchange,提问作者Francis S
相关产品推荐
相关产品推荐

