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

.NET Core 6.0 Google登录时ClaimsPrincipal.Identities返回null问题

问题分析与修复方案

核心问题

  1. 中间件配置缺失与顺序错误:你的Program.cs中未添加app.UseAuthentication()中间件,且UseSession的位置不符合ASP.NET Core中间件执行顺序要求,导致认证流程无法正常触发。
  2. 回调方法逻辑错误:在GoogleLoginProc中,你直接尝试通过Cookie认证方案获取用户信息,但此时Google OAuth回调后的用户身份还未被保存到Cookie中,因此result.Principal为null,进而引发Identities空引用错误。

修复步骤

1. 修正Program.cs中间件配置

调整中间件顺序并添加认证中间件:

using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.Cookie.Name = ".Cookies.NetCoreSocialLogin";
    options.LoginPath = new PathString("/account/login");
    options.LogoutPath = new PathString("/account/logout");
    options.AccessDeniedPath = new PathString("/error/403");
})
.AddGoogle(options =>
{
    options.CallbackPath = "/account/signin-google";
    options.ClientId = "你的ClientId";
    options.ClientSecret = "你的ClientSecret";
});


var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseSession(); // 调整到路由中间件之前
app.UseRouting();

app.UseAuthentication(); // 添加认证中间件,必须在授权中间件之前
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

2. 修正AccountController的回调方法逻辑

修改GoogleLoginProc,先获取Google OAuth的认证结果,再将用户身份保存到Cookie中:

using netcore_social_login.Dtos;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Mvc;

namespace netcore_social_login.Controllers
{
    [Route("account")]
    public class AccountController : Controller
    {
        [HttpGet("login")]
        public IActionResult GoogleLogin()
        {
            var properties = new AuthenticationProperties
            {
                RedirectUri = Url.Action("GoogleLoginProc")
            };

            return Challenge(properties, GoogleDefaults.AuthenticationScheme);
        }

        [HttpGet("signin-google")] 
        public async Task<IActionResult> GoogleLoginProc()
        {
            // 先获取Google OAuth的认证结果
            var result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);
            
            if (!result.Succeeded)
            {
                // 认证失败时跳转回登录页
                return RedirectToAction("Login");
            }

            // 提取Google返回的身份信息
            var googleIdentity = result.Principal.Identities.FirstOrDefault();
            if (googleIdentity == null)
            {
                return RedirectToAction("Login");
            }

            var claims = googleIdentity.Claims.Select(claim => new ClaimJson
            {
                Issuer = claim.Issuer,
                OriginalIssuer = claim.OriginalIssuer,
                Type = claim.Type,
                Value = claim.Value,
                ValueType = claim.ValueType
            }).ToList();

            var providerKey = claims
                .Where(x => x.Type.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"))
                .Select(x => x.Value)
                .FirstOrDefault();

            var emailAddress = claims
                .Where(x => x.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")
                .Select(x => x.Value)
                .FirstOrDefault();

            // 创建Cookie认证所需的身份信息
            var claimsIdentity = new ClaimsIdentity(googleIdentity.Claims, CookieAuthenticationDefaults.AuthenticationScheme);
            var authProperties = new AuthenticationProperties
            {
                IsPersistent = false // 根据需求设置是否持久化登录
            };

            // 将用户身份保存到Cookie中,后续请求可通过Cookie获取用户信息
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);

            return RedirectToAction("Index", "Home");
        }
    }
}

关键说明

  • 中间件顺序必须严格遵循:静态文件 → Session → 路由 → 认证 → 授权,否则认证流程会失效。
  • 回调方法中需先通过Google认证方案获取用户信息,再将其转换为Cookie认证的身份,这样后续请求才能通过Cookie正常获取用户Principal。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:48:09