为什么 Google 提供商身份验证不存在生日声明?

Why doesn't exist birthday claim on Google provider authentication?

应用程序:.Net Core 3 with Identity。

当应用使用 Google 进行身份验证时,它会获取照片、区域设置、用户姓氏、用户名... 但是我不能过生日。我在互联网上搜索了两天,但没有得到解决方案。

Startup.cs

services.AddAuthentication()
                .AddGoogle(options =>
                {                    
                    IConfigurationSection googleAuthNSection =
                        Configuration.GetSection("Authentication:Google");
                    options.ClientId = googleAuthNSection["ClientId"];
                    options.ClientSecret = googleAuthNSection["ClientSecret"]; 
                     // scope for birthday
                    options.Scope.Add("https://www.googleapis.com/auth/user.birthday.read");                   
                    options.AuthorizationEndpoint += "?prompt=consent";                   
                    options.AccessType = "offline";
                    options.ClaimActions.MapJsonKey("avatar", "picture", "url");
                     options.ClaimActions.MapJsonKey("locale", "locale", "string");

                    // all they don't work:
                    //options.ClaimActions.MapJsonKey("birthday", "birthday", ClaimValueTypes.String);
                    //options.ClaimActions.MapJsonKey(ClaimTypes.DateOfBirth, "birthdays");
                    options.ClaimActions.MapJsonKey(ClaimTypes.DateOfBirth, "birthdays", ClaimValueTypes.String);                   
                    options.SaveTokens = true;

                    options.Events.OnCreatingTicket = ctx =>
                    {
                        List<AuthenticationToken> tokens = ctx.Properties.GetTokens().ToList();

                        tokens.Add(new AuthenticationToken()
                        {
                            Name = "TicketCreated",
                            Value = DateTime.UtcNow.ToString()
                        });


                        ctx.Properties.StoreTokens(tokens);

                        return Task.CompletedTask;
                    };
                });

Account/ExternalLoginModel.cs

 public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
{
//....
 var info = await _signInManager.GetExternalLoginInfoAsync();
// Sign in the user with this external login provider if the user already has a login.
 var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);

foreach (var i in info.Principal.Claims)
{
   // get all claims from Google, except birthday.
   Console.WriteLine(i.Type + " " + i.Value);
}

}

Google OAuth 同意屏幕

我在 https://developers.google.com/people/api/rest/v1/people/get 生日:

"birthdays": [
    {
      "metadata": {
        "primary": true,
        "source": {
          "type": "PROFILE",
          "id": "11"
        }
      },
      "date": {
        "year": 1930,
        "month": 12,
        "day": 26
      }...

如何获得 .Net Core 生日声明?

我遇到了同样的问题。我还尝试使用 Google OpenId Connect REST APIs 并且即使我将“https://www.googleapis.com/auth/user.birthday.read”范围添加到身份验证请求也不会返回所需的数据。

根据我的搜索,"Gender" 和 "birthdays" 等字段不是标准的一部分,您需要访问提供商 API 才能获取此类信息。

我使用的是 IdentityServer4,所以我在 ProfileService 中添加了代码以获取所需的声明并将它们添加到用户声明中:


// Create Credentials required from access token
// PeopleServiceService nuget:Google.Apis.PeopleService.v1

var cred = GoogleCredential.FromAccessToken("ACCESS_TOKEN");
var peopleServiceService = new PeopleServiceService(
    new BaseClientService.Initializer() { HttpClientInitializer = cred });

// use people/me to access data for the current authenticated user 
var personRequest = peopleServiceService.People.Get("people/me");
personRequest.PersonFields = "birthdays,genders";

Person person = peopleRequest.Execute();

// you can access now 
// person.Genders, person.Birthdays


在您的情况下,您可以在 'OnCreatingTicket' 执行时添加声明:


// options.Events.OnCreatingTicket = ctx => { --> 

Person person = peopleRequest.Execute();
var genderValue = person.Genders?.FirstOrDefault()?.FormattedValue;

var claimsIdentity = ctx.Principal.Identities.First();
claimsIdentity.AddClaim(new Claim("Gender", genderValue));


tokens.Add(new AuthenticationToken()
           {
               Name = "TicketCreated",
               Value = DateTime.UtcNow.ToString()
           });


人员API 文档: https://developers.google.com/people/api/rest/v1/people/get