Ok... I'm currently using ASP.Net Core 1.1.2 with ASP.NET Core Identity 1.1.2.
The important part in Startup.cs looks like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
app.UseGoogleAuthentication(new GoogleOptions
{
AuthenticationScheme = "Google",
SignInScheme = "Identity.External", // this is the name of the cookie middleware registered by UseIdentity()
ClientId = Configuration["ExternalLoginProviders:Google:ClientId"],
ClientSecret = Configuration["ExternalLoginProviders:Google:ClientSecret"]
});
}
GoogleOptions comes with Microsoft.AspNetCore.Authentication.Google nuget package.
The callback function in AccountController.cs looks like this:
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
//... SignInManager<User> _signInManager; declared before
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
SignInResult signInResult = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
string email = info.Principal.FindFirstValue(ClaimTypes.Email);
string firstName = info.Principal.FindFirstValue(ClaimTypes.GivenName);
string lastName = info.Principal.FindFirstValue(ClaimTypes.Surname);
//
}
So, everything works fine until this point. And here I'm stuck. I read a lot of articles about accesstokens and claims called pictureUrl and so on. But the Principal doesn't contain any of those.
So the question is: How to retrieve the profile image once in the ExternalLoginCallback function?
I struggled with the same problem but on ASP.NET Core 2.0.
There is a better aproach to retrieve the picture from the OnCreatingTicket
event in your startup.cs
. In your case you have to add the specific claim "picture" to the identity.
public void ConfigureServices(IServiceCollection services)
{
services
.AddAuthentication()
.AddCookie()
.AddGoogle(options =>
{
options.ClientId = Configuration["Google.LoginProvider.ClientId"];
options.ClientSecret = Configuration["Google.LoginProvider.ClientKey"];
options.Scope.Add("profile");
options.Events.OnCreatingTicket = (context) =>
{
context.Identity.AddClaim(new Claim("image", context.User.GetValue("image").SelectToken("url").ToString()));
return Task.CompletedTask;
};
});
}
Then in your AccountController you can select the image from the external login info method.
var info = await _signInManager.GetExternalLoginInfoAsync();
var picture = info.Principal.FindFirstValue("image");
For .net core 3.0+, Microsoft uses System.Text.Json for handling returned object from google, so we need to use GetProperty method of this new API to get picture.
https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/
services.AddAuthentication()
.AddGoogle(options =>
{
IConfigurationSection googleAuthNSection = Configuration.GetSection("Authentication:Google");
options.ClientId = googleAuthNSection["ClientId"];
options.ClientSecret = googleAuthNSection["ClientSecret"];
options.Scope.Add("profile");
options.Events.OnCreatingTicket = (context) =>
{
var picture = context.User.GetProperty("picture").GetString();
context.Identity.AddClaim(new Claim("picture", picture));
return Task.CompletedTask;
};
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With