.NET 8升级后用机器名HTTP访问时OIDC关联失败问题
.NET 8 OIDC "Correlation failed" 问题(HTTP+机器名场景)
问题根源
.NET 8 对 Cookie 策略做了默认强化:
- 默认
CookieSecurePolicy为SameAsRequest,但部分浏览器在非 localhost 的 HTTP 环境下会强制拒绝非 Secure 的 Cookie - OIDC 流程中的关联 Cookie(Correlation Cookie)和 Nonce Cookie 默认继承全局策略,导致 HTTP+机器名场景下 Cookie 无法在客户端和 IdentityServer 之间传输,触发 "Correlation failed" 错误
解决方案
1. 显式关闭 Cookie 的 Secure 策略
在主应用和 IdentityServer 中,针对 OIDC 相关 Cookie 和认证 Cookie 强制关闭 Secure 要求:
主应用(.NET 8)配置示例
builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(options => { // 允许 HTTP 环境下发送认证 Cookie options.Cookie.SecurePolicy = CookieSecurePolicy.None; options.Cookie.SameSite = SameSiteMode.Lax; // 若主应用与 IdentityServer 共享域名/机器名,可设置 Domain 确保 Cookie 跨端口共享 // options.Cookie.Domain = "machine-name"; }) .AddOpenIdConnect(options => { options.Authority = "http://machine-name:5000"; // 替换为你的 IdentityServer 地址 options.ClientId = "your-client-id"; options.ClientSecret = "your-client-secret"; options.ResponseType = "code"; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; // 配置 OIDC 关联 Cookie 和 Nonce Cookie options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.None; options.CorrelationCookie.SameSite = SameSiteMode.Lax; options.NonceCookie.SecurePolicy = CookieSecurePolicy.None; options.NonceCookie.SameSite = SameSiteMode.Lax; // 确保回调地址与客户端配置一致(使用机器名) options.CallbackPath = "/signin-oidc"; options.SignedOutCallbackPath = "/signout-callback-oidc"; });
IdentityServer(.NET Framework 4.6.2)配置示例
在 Startup.cs 的 ConfigureServices 中添加:
// 覆盖 IdentityServer 默认 Cookie 策略 services.Configure<CookieAuthenticationOptions>(IdentityServerConstants.DefaultCookieAuthenticationScheme, options => { options.Cookie.SecurePolicy = CookieSecurePolicy.None; options.Cookie.SameSite = SameSiteMode.Lax; });
2. 修正 OIDC 客户端配置
确保 IdentityServer 的客户端配置中,RedirectUris 和 PostLogoutRedirectUris 使用机器名的 HTTP 地址,例如:
// IdentityServer 客户端配置示例 { "ClientId": "your-client-id", "RedirectUris": [ "http://machine-name:5001/signin-oidc" ], "PostLogoutRedirectUris": [ "http://machine-name:5001/signout-callback-oidc" ], // 其他配置... }
3. 调整主机名与 Cookie 域配置
- 在主应用
Program.cs中确保允许机器名访问:builder.WebHost.ConfigureKestrel(options => { // 监听所有 IP 或指定机器名对应 IP options.ListenAnyIP(5001); }); // 或在 appsettings.json 中设置 // "AllowedHosts": "machine-name,localhost,127.0.0.1" - 若主应用与 IdentityServer 在同一机器不同端口,设置
Cookie.Domain = "machine-name"确保 Cookie 跨端口共享
4. 避免使用 SameSite=None(HTTP 场景)
HTTP 环境下,浏览器会拦截标记为 SameSite=None 的 Cookie,因此需将所有相关 Cookie 的 SameSite 设置为 Lax 或 Unspecified(.NET 8 新增,对应不设置 SameSite 属性)
额外注意事项
- 测试前清除浏览器缓存和 Cookie,避免旧策略的 Cookie 干扰
- 部分浏览器(如 Chrome)的隐私设置可能会限制 HTTP 环境下的跨主机 Cookie,可临时降低隐私级别测试
- 若仍存在循环跳转,可在
OnRemoteFailure事件中添加日志,排查具体失败原因:options.Events.OnRemoteFailure = context => { // 记录失败日志 var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>(); logger.LogError(context.Failure, "OIDC 远程失败"); context.Response.Redirect("/"); context.HandleResponse(); return Task.CompletedTask; };
内容的提问来源于stack exchange,提问作者Xytech
相关产品推荐
相关产品推荐

