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

跨域Silent Renew异常求助:client2.com触发login_required错误

问题

我有两个不同域名的客户端client1.com、client2.com,Identity Server部署在auth.client1.com。其中client1.com的静默续期(Silent Renew)功能正常,但client2.com执行静默续期时触发错误,页面变为空白,错误信息如下:

"Error: AuthCallback AuthResult came with error: login_required"

附上我的Startup.cs代码:

public void ConfigureServices(IServiceCollection services)
{
    services.ConfigureNonBreakingSameSiteCookies();
    services.AddControllersWithViews();

    string migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
    string connectionString = "<connectionString>";

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(connectionString));

    services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

    var builder = services.AddIdentityServer(options =>
    {
        options.Events.RaiseErrorEvents = true;
        options.Events.RaiseInformationEvents = true;
        options.Events.RaiseFailureEvents = true;
        options.Events.RaiseSuccessEvents = true;
    })
                     .AddConfigurationStore(options =>
                     {
                         options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
                             sql => sql.MigrationsAssembly(migrationsAssembly));
                     })
                     .AddOperationalStore(options =>
                     {
                         options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
                             sql => sql.MigrationsAssembly(migrationsAssembly));
                         options.EnableTokenCleanup = true;
                     }).AddAspNetIdentity<ApplicationUser>();

    string cerFileName = "<cerFileName>";
    string cerPassword = "<cerPassword>";

    if (Environment.IsDevelopment())
    {
        string fileName = Path.Combine(Environment.ContentRootPath, "tempkey.rsa");
        builder.AddDeveloperSigningCredential(filename: fileName);
    }
    else
    {
        if (!File.Exists(cerFileName))
        {
            throw new FileNotFoundException("Signing Certificate is missing!");
        }

        X509Certificate2 cert = new X509Certificate2(cerFileName, cerPassword, X509KeyStorageFlags.MachineKeySet);
        builder.AddSigningCredential(cert);
        Console.WriteLine("###Certificate is done");
    }

    string authorityUrl = Configuration.GetValue<string>("<AuthorityUrl>");

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
      .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, jwt =>
      {
          jwt.Authority = authorityUrl;

          jwt.TokenValidationParameters = new TokenValidationParameters()
          {
              ValidateAudience = false,
          };
          jwt.RequireHttpsMetadata = false;
      });

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();

    services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
}

public void Configure(IApplicationBuilder app)
{
    using (var scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
    {
        SeedData.EnsureSeedData(scope.ServiceProvider, Configuration);
    }

    app.UseCookiePolicy();

    if (Environment.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseIdentityServer();

    ///app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}
排查与解决方案

login_required错误在跨域静默续期场景下,通常是Identity Server无法识别客户端的登录会话,或跨域配置缺失导致,你需要检查并补充以下配置:

  • Identity Server的Cookie跨域适配
    由于client2.com与auth.client1.com跨域,需要调整登录Cookie的属性,确保跨域请求能携带会话凭证:

    services.ConfigureApplicationCookie(options =>
    {
        options.Cookie.SameSite = SameSiteMode.None;
        options.Cookie.Domain = ".client1.com"; // 开头的点适配所有子域
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 生产环境必须配合HTTPS
    });
    

    同时确保ConfigureNonBreakingSameSiteCookies()的配置不会覆盖上述SameSite设置。

  • client2的Identity Server客户端配置
    检查Identity Server中client2.com的客户端元数据,确保:

    • AllowedCorsOrigins包含https://client2.com(完整域名);
    • AllowedGrantTypes包含implicit或authorization_code(匹配你的静默续期流程);
    • RedirectUris添加静默续期回调地址(比如https://client2.com/silent-renew.html);
    • AllowAccessTokensViaBrowser设置为true,允许浏览器端获取令牌。
  • 添加CORS中间件并调整顺序
    在Configure方法中,将CORS中间件放在UseIdentityServer之前,允许跨域携带凭证:

    app.UseCors(options =>
    {
        options.WithOrigins("https://client1.com", "https://client2.com")
               .AllowAnyHeader()
               .AllowAnyMethod()
               .AllowCredentials(); // 必须开启,允许携带Cookie
    });
    app.UseIdentityServer();
    
  • 客户端静默续期请求配置
    客户端发起静默续期时,必须开启withCredentials: true,确保请求携带Identity Server的登录Cookie。以oidc-client-js为例:

    const userManager = new UserManager({
        authority: 'https://auth.client1.com',
        client_id: 'client2',
        redirect_uri: 'https://client2.com/callback.html',
        silent_redirect_uri: 'https://client2.com/silent-renew.html',
        response_type: 'id_token token',
        scope: 'openid profile',
        withCredentials: true // 关键配置,确保携带Cookie
    });
    
  • HTTPS环境检查
    生产环境中,SameSite=None的Cookie要求必须使用HTTPS,否则浏览器会拒绝携带凭证;开发环境需启用ASP.NET Core的开发HTTPS证书。

内容的提问来源于stack exchange,提问作者HasanGundogdu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:25:31