You need to enable JavaScript to run this app. ASP.NET Core Blazor接入Google登录时AuthenticateResult.Principal为null问题
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Blazor接入Google登录时AuthenticateResult.Principal为null问题

问题根因

  1. 回调方法认证Scheme调用错误
    GoogleResponse方法中调用HttpContext.AuthenticateAsync时传入的是CookieAuthenticationDefaults.AuthenticationScheme,该Scheme对应本地Cookie认证体系。Google账号刚完成授权时,还未完成向本地Cookie的转换,直接调用Cookie认证的校验逻辑自然无法返回有效Principal对象。
  2. Identity配置与自定义认证配置冲突
    代码中同时注册了AddIdentity<User, Role>()和自定义AddCookie配置,AddIdentity会默认覆盖全局认证Scheme配置,导致Google认证与本地Cookie认证的联动逻辑失效。
  3. 缺少Google认证的SignInScheme显式配置
    Google认证配置未指定SignInScheme参数,导致Google授权完成后无法将认证信息写入到对应认证体系中,返回结果自然所有字段为空。

修复方案

保留Identity场景修复步骤

1. 调整Startup.cs认证配置

修改ConfigureServices方法中认证相关配置调整如下:

// Identity配置保持不变,调整AddAuthentication配置顺序与参数
services.AddIdentity<User, Role>()
    .AddEntityFrameworkStores<Context>()
    .AddDefaultTokenProviders();

services.AddAuthentication(options =>
{
    options.DefaultScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddGoogle(options =>
{
    options.ClientId = Configuration["Google:ClientID"];
    options.ClientSecret = Configuration["Google:ClientSecret"];
    // 指定Google认证完成后写入Identity外部登录临时Scheme
    options.SignInScheme = IdentityConstants.ExternalScheme;
});
// 移除重复的AddCookie配置,Identity已内置Cookie认证逻辑

2. 调整LoginController的GoogleResponse逻辑

[Route("google-response")]
public async Task<IActionResult> GoogleResponse()
{
    // 读取Identity外部登录临时Scheme的认证结果
    var externalAuthResult = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
    if (!externalAuthResult.Succeeded || externalAuthResult.Principal == null)
    {
        return RedirectToAction("GoogleLogin");
    }
    var claims = externalAuthResult.Principal.Identities.FirstOrDefault()?.Claims.Select(claim => new
    {
        claim.Issuer,
        claim.OriginalIssuer,
        claim.Type,
        claim.Value
    }) ?? Enumerable.Empty<object>();
    // 可选:完成本地登录写入Cookie
    await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, 
        new ClaimsPrincipal(new ClaimsIdentity(externalAuthResult.Principal.Claims, IdentityConstants.ApplicationScheme)));
    // 清理外部登录临时Cookie
    await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
    return Json(claims);
}

无Identity场景修复步骤

如果不需要Identity的用户名密码登录功能,仅保留Google第三方登录,可以直接移除AddIdentity相关配置,调整逻辑如下:

1. 调整Startup.cs配置

移除services.AddIdentity<User, Role>().AddEntityFrameworkStores<Context>()相关代码,调整AddAuthentication配置:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    options.LoginPath = "/login/google-login";
})
.AddGoogle(options =>
{
    options.ClientId = Configuration["Google:ClientID"];
    options.ClientSecret = Configuration["Google:ClientSecret"];
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
});

2. 调整GoogleResponse逻辑:

[Route("google-response")]
public async Task<IActionResult> GoogleResponse()
{
    var authResult = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);
    if (!authResult.Succeeded || authResult.Principal == null)
    {
        return RedirectToAction("GoogleLogin");
    }
    // 写入本地Cookie
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, authResult.Principal);
    var claims = authResult.Principal.Identities.FirstOrDefault().Claims.Select(claim => new
    {
        claim.Issuer,
        claim.OriginalIssuer,
        claim.Type,
        claim.Value
    });
    return Json(claims);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 23:15:01