ASP.NET Core Blazor接入Google登录时AuthenticateResult.Principal为null问题
问题根因
- 回调方法认证Scheme调用错误
GoogleResponse方法中调用HttpContext.AuthenticateAsync时传入的是CookieAuthenticationDefaults.AuthenticationScheme,该Scheme对应本地Cookie认证体系。Google账号刚完成授权时,还未完成向本地Cookie的转换,直接调用Cookie认证的校验逻辑自然无法返回有效Principal对象。 - Identity配置与自定义认证配置冲突
代码中同时注册了AddIdentity<User, Role>()和自定义AddCookie配置,AddIdentity会默认覆盖全局认证Scheme配置,导致Google认证与本地Cookie认证的联动逻辑失效。 - 缺少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
相关产品推荐
相关产品推荐

