You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:55:10