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

.NET 8 Blazor WebAssembly集成Google登录时出现Correlation failed错误排查

.NET 8 Blazor WASM集成Identity与Google认证时出现Correlation Failed错误排查

我正在使用.NET 8 Blazor WebAssembly,单独使用Identity认证或Google认证均能正常工作,但将二者集成时出现了Correlation failed错误。

错误日志

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
Microsoft.AspNetCore.Authentication.AuthenticationFailureException: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.AuthenticationFailureException: Correlation failed.
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context).

项目配置代码

using DNAiWeb.Client.Pages;
using DNAiWeb.Components;
using MudBlazor.Services;
using DNAiBase.Services;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using DNAiWeb.Components.Account;
using DNAiBase.Data;
using DNAiBase.Models;
using Npgsql.EntityFrameworkCore.PostgreSQL;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;

var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
var configuration = builder.Configuration;

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<IdentityUserAccessor>();
builder.Services.AddScoped<IdentityRedirectManager>();
builder.Services.AddScoped<AuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider>();

/*builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    //options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
}).AddCookie()
    .AddIdentityCookies();

services.AddAuthentication(options =>
{
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
    }).AddGoogle(googleOptions =>{
    googleOptions.ClientId = ""; // Replace with your Google client ID
    googleOptions.ClientSecret = ""; // Replace with your Google client secret
    googleOptions.CallbackPath = "/signin-google"; // Set the redirect URI
}).AddCookie()
   .AddIdentityCookies(); */

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme; // Set Google as default challenge scheme
}).AddCookie(IdentityConstants.ApplicationScheme) // Add cookie authentication with IdentityConstants.ApplicationScheme
.AddCookie(IdentityConstants.ExternalScheme);// Add cookie authentication with IdentityConstants.ExternalScheme

services.AddAuthentication().AddGoogle(googleOptions =>{
    googleOptions.ClientId = "";
    googleOptions.ClientSecret = "";
    googleOptions.CallbackPath = "/signin-google";
});

/*builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    //options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
}).AddCookie().AddIdentityCookies();

// Configure services for Google authentication
services.AddAuthentication()
    .AddGoogle(options =>
    {
        options.ClientId = ""; // Replace with your Google client ID
        options.ClientSecret = ""; // Replace with your Google client secret
        options.CallbackPath = "/signin-google"; // Set the redirect URI
    }); */

var connectionString = builder.Configuration.GetConnectionString("postgresConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseNpgsql(connectionString, b => b.MigrationsAssembly("DNAiWeb")));

builder.Services.AddIdentityCore<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddSignInManager()
    .AddDefaultTokenProviders();

builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();

builder.Services.AddMudServices();
builder.Services.AddScoped<UserScopedService>();
builder.Services.AddScoped<DNAiOpenAI>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();
}
else
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseAntiforgery();

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

app.UseMiddleware<BlazorCookieLoginMiddleware>();

app.MapAdditionalIdentityEndpoints();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(Counter).Assembly);

app.MapGet("/signin-google", () => new GoogleAuthController());

app.Run();

问题原因与修复方案

问题原因

  1. 重复注册Authentication服务:代码中多次调用services.AddAuthentication(),导致认证配置被覆盖,第三方登录所需的关联Cookie无法正常生成或读取。
  2. Scheme配置混乱:默认Scheme、SignInScheme的设置逻辑冲突,Identity外部登录需要依赖IdentityConstants.ExternalScheme处理临时凭证,当前配置未正确关联。
  3. 错误的回调路由映射:手动添加的/signin-google路由覆盖了Google认证中间件的默认回调处理,导致关联验证流程中断。

修复步骤

1. 统一认证服务配置

替换所有认证注册代码为以下内容,确保只初始化一次认证服务:

services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddIdentityCookies() // 自动配置Identity所需的Cookie Scheme
.AddGoogle(googleOptions =>
{
    googleOptions.ClientId = ""; // 替换为你的Google Client ID
    googleOptions.ClientSecret = ""; // 替换为你的Google Client Secret
    googleOptions.CallbackPath = "/signin-google";
});
  • AddIdentityCookies()会自动注册IdentityConstants.ApplicationScheme和IdentityConstants.ExternalScheme,无需手动添加AddCookie。
  • 明确设置DefaultChallengeScheme为Google,确保触发第三方登录时使用正确的认证流程。

2. 移除错误的路由映射

删除以下代码行,Google认证中间件会自动处理回调请求:

app.MapGet("/signin-google", () => new GoogleAuthController());

3. 验证中间件顺序

确保中间件顺序遵循以下逻辑:

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.UseAuthentication(); // 认证必须在授权之前
app.UseAuthorization();
app.UseMiddleware<BlazorCookieLoginMiddleware>();

4. 检查Google控制台配置

确认Google开发者控制台中授权重定向URI与项目CallbackPath一致,格式为https://<你的域名>/signin-google(开发环境使用https://localhost:<端口>/signin-google)。

5. 强制使用HTTPS

开发环境中必须启用HTTPS,第三方认证服务要求回调地址使用HTTPS,否则关联Cookie无法正确传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:07:40