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

ASP.NET Core跨站生成Windows认证Cookie实现共享登录遇阻

问题诊断与修复方案

你的核心问题是Windows认证站点生成的Cookie无法被Identity主站识别,主要原因是Cookie配置不匹配、缺少Identity必需的Claims,以及认证Scheme不一致。以下是具体修复步骤:

一、修正Windows认证站点配置

1. 调整认证服务配置

ConfigureApplicationCookie是用于配置Identity内置Cookie的,你手动添加的Cookie认证方案需要单独配置,确保和主站Cookie参数完全一致:

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddCookie("CookieAuthenticationScheme", options =>
    {
        options.Cookie.Name = ".AspNet.SharedCookie";
        options.Cookie.Domain = "localhost"; // 本地测试用,生产环境改为共同父域名(如.example.com)
        options.Cookie.Path = "/";
        options.Cookie.SameSite = SameSiteMode.Lax; // 跨站场景下使用Lax/None(None需HTTPS)
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 生产环境强制HTTPS,本地可改为SameAsRequest
        // 确保TicketDataFormat使用和主站一致的数据保护密钥
        var dataProtector = builder.Services.BuildServiceProvider()
            .GetRequiredService<IDataProtectionProvider>()
            .CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "CookieAuthenticationScheme", "v2");
        options.TicketDataFormat = new TicketDataFormat(dataProtector);
    })
    .AddNegotiate();

// 数据保护配置保持不变
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\KeyLocation"))
    .SetApplicationName("SharedCookieApp");

2. 修正SignIn逻辑

Identity需要特定Claims才能识别登录状态,必须包含NameIdentifier和SecurityStamp,同时使用主站的认证Scheme(默认是Identity.Application):

public class HomeController : Controller
{
    // 若共享数据库,可注入UserManager获取用户信息;否则调用主站API获取SecurityStamp
    // private readonly UserManager<IdentityUser> _userManager;
    // public HomeController(UserManager<IdentityUser> userManager) => _userManager = userManager;

    public async Task<IActionResult> Index()
    {
        var userName = HttpContext.User.Identity?.Name;

        if (userName != null)
        {
            var targetUserName = "TestUser@test.com";
            // 替换为实际获取用户SecurityStamp的逻辑
            var securityStamp = "从主站/数据库获取的对应用户SecurityStamp";

            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, targetUserName),
                new Claim(ClaimTypes.NameIdentifier, targetUserName),
                new Claim("AspNet.Identity.SecurityStamp", securityStamp)
            };

            // 使用主站Identity的认证Scheme名称
            var identity = new ClaimsIdentity(claims, "Identity.Application");
            await HttpContext.SignInAsync("CookieAuthenticationScheme", new ClaimsPrincipal(identity));
        }

        return Redirect("https://localhost:7207");
    }
}

二、修正Identity主站配置

确保主站Cookie配置与Windows站点完全匹配,同时明确Identity的Cookie参数:

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

// 数据保护配置保持不变
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"c:\KeyLocation"))
    .SetApplicationName("SharedCookieApp");

// 配置Identity的Cookie,和Windows站点参数完全一致
builder.Services.ConfigureApplicationCookie(options =>
{
    options.Cookie.Name = ".AspNet.SharedCookie";
    options.Cookie.Domain = "localhost";
    options.Cookie.Path = "/";
    options.Cookie.SameSite = SameSiteMode.Lax;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.LoginPath = "/Account/Login";
    options.LogoutPath = "/Account/Logout";
});

三、关键注意事项

  • 密钥权限:运行两个站点的Windows账户必须对c:\KeyLocation目录有读写权限,否则数据保护无法正常工作。
  • 跨站Cookie:若两个站点域名不同,需将Cookie.Domain设置为共同的父域名(如.yourcompany.com),同时SameSite设为Lax或None(None要求站点使用HTTPS)。
  • SecurityStamp一致性:SecurityStamp必须和主站Identity中对应用户的SecurityStamp完全一致,否则Identity会判定Cookie无效。
  • Scheme匹配:Windows站点SignIn时使用的ClaimsIdentity认证类型(Identity.Application)必须和主站Identity的Scheme一致,可通过主站AddDefaultIdentity的配置确认。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:34:52