ASP.NET Core集成Google登录:使用Google Bearer Token仍未授权
解决方案
方案一:配置JWT验证直接支持Google Access Token
你可以在Program.cs(或旧版的Startup.cs)中添加针对Google的JWTBearer验证方案,让应用同时兼容自身Identity Token和Google Token的验证。
配置代码示例:
// 注册认证服务,保留原有Identity的Bearer验证,新增Google的验证方案 builder.Services.AddAuthentication() // 原有ASP.NET Identity JWT验证配置 .AddJwtBearer("IdentityBearer", options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidateAudience = true, ValidAudience = builder.Configuration["Jwt:Audience"], ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; }) // 新增Google JWT验证 .AddJwtBearer("GoogleBearer", options => { options.Authority = "https://accounts.google.com"; options.Audience = builder.Configuration["Google:ClientId"]; // 你的Google Client ID options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "https://accounts.google.com", ValidateAudience = true, ValidAudience = builder.Configuration["Google:ClientId"], ValidateLifetime = true }; }); // 设置默认授权策略,允许两种Token通过验证 builder.Services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes("IdentityBearer", "GoogleBearer") .Build(); });
配置完成后,无论是应用自身生成的Bearer Token,还是Google返回的Access Token,都能通过[Authorize]特性的验证。
方案二:将Google登录转换为ASP.NET Identity登录(推荐)
更符合ASP.NET Identity设计的做法是:拿到Google Token并验证用户身份后,为用户生成应用自身的认证票据(或JWT Token),后续请求统一使用应用自有Token,避免维护多套验证逻辑。
实现步骤:
- 解析Google Token,获取用户信息
// 先定义对应的模型类 public class GoogleTokenResponse { public string AccessToken { get; set; } public string IdToken { get; set; } public int ExpiresIn { get; set; } public string TokenType { get; set; } } public class GoogleUserInfo { public string Sub { get; set; } public string Email { get; set; } public bool EmailVerified { get; set; } public string Name { get; set; } public string Picture { get; set; } } // 解析Token并获取用户信息 var tokenContent = await tokenResponse.Content.ReadFromJsonAsync<GoogleTokenResponse>(); var userInfoResp = await _httpClient.GetAsync($"https://www.googleapis.com/oauth2/v3/userinfo?access_token={tokenContent.AccessToken}"); var userInfo = await userInfoResp.Content.ReadFromJsonAsync<GoogleUserInfo>();
- 查找或创建Identity用户
var userManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>(); var user = await userManager.FindByEmailAsync(userInfo.Email); if (user == null) { user = new IdentityUser { UserName = userInfo.Email, Email = userInfo.Email, EmailConfirmed = userInfo.EmailVerified }; await userManager.CreateAsync(user); }
- 生成应用自有认证凭证
- 如果是Cookie认证(MVC场景):
var signInManager = serviceProvider.GetRequiredService<SignInManager<IdentityUser>>(); await signInManager.SignInAsync(user, isPersistent: false); // 之后跳转至主页,用户通过Cookie保持登录状态
- 如果是JWT认证(API场景):
var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Email, user.Email), new Claim(ClaimTypes.Name, userInfo.Name) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwtToken = new JwtSecurityToken( issuer: builder.Configuration["Jwt:Issuer"], audience: builder.Configuration["Jwt:Audience"], claims: claims, expires: DateTime.Now.AddHours(1), signingCredentials: creds); var tokenString = new JwtSecurityTokenHandler().WriteToken(jwtToken); // 将tokenString返回给前端,后续请求用此作为Bearer Token
方案对比
- 方案一适合需要同时兼容两种Token的场景,但需维护两套验证配置。
- 方案二统一使用应用自身的认证体系,后续扩展(如添加角色权限、自定义Claims)更方便,是生产环境的推荐做法。
内容的提问来源于stack exchange,提问作者Michał Turczyn
相关产品推荐
相关产品推荐

