好的......我目前正在使用ASP.Net Core 1.1.2和ASP.NET Core Identity 1.1.2。
Startup.cs 中的重要部分如下所示:
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附带Microsoft.AspNetCore.Authentication.Google nuget包。
AccountController.cs 中的回调函数如下所示:
[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);
//
}
所以,到目前为止,一切正常。在这里,我被困住了。我读了很多关于accessstokens和声称的文章,名为pictureUrl等。但校长不包含任何这些。
所以问题是:如何在ExternalLoginCallback函数中检索一次配置文件图像?
答案 0 :(得分:7)
我在ASP.NET Core 2.0上遇到了同样的问题。
从OnCreatingTicket
startup.cs
事件中检索图片有一个更好的方法。在您的情况下,您必须将特定声明&#34;图片&#34; 添加到身份中。
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;
};
});
}
然后在您的AccountController中,您可以从外部登录信息方法中选择图像。
var info = await _signInManager.GetExternalLoginInfoAsync();
var picture = info.Principal.FindFirstValue("image");
答案 1 :(得分:7)
对于.net core 3.0 +,Microsoft使用System.Text.Json来处理从Google返回的对象,因此我们需要使用此新API的GetProperty方法来获取图片。
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;
};
});
答案 2 :(得分:1)
我发现无法从索赔中获取图片网址。最后,我找到了一个使用nameidentifier的解决方案,该解决方案随附声明。
string googleApiKey = _configurationRoot["ExternalLoginProviders:Google:ApiKey"];
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
string nameIdentifier = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
string jsonUrl = $"https://www.googleapis.com/plus/v1/people/{nameIdentifier}?fields=image&key={googleApiKey}";
using (HttpClient httpClient = new HttpClient())
{
string s = await httpClient.GetStringAsync(jsonUrl);
dynamic deserializeObject = JsonConvert.DeserializeObject(s);
string thumbnailUrl = (string)deserializeObject.image.url;
byte[] thumbnail = await httpClient.GetByteArrayAsync(thumbnailUrl);
}
您只需要一个Google API密钥。
创建API密钥:
启用Google+ API服务:
一个。在Google API列表中,搜索Google+ API服务。
湾从结果列表中选择Google+ API。
℃。按“启用API”按钮。
此过程完成后,Google+ API会显示在已启用的API列表中。至 访问,选择API&amp;左侧边栏菜单上的服务,然后选择 启用API选项卡。
在&#34; API&amp;服务&#34;,选择凭据。
答案 3 :(得分:0)
您可以在GoogleOptions
设置中提供要请求的其他范围。您正在寻找的范围是profile
范围,通过其他声明可以访问名字,姓氏和个人资料照片:https://developers.google.com/identity/protocols/OpenIDConnect#discovery
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"]});
Scopes = { "profile" };
}
然后,您可以在身份验证成功后检索控制器中的图片声明:
[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);
// profile claims
string picture = info.Principal.FindFirstValue("picture");
string firstName = info.Principal.FindFirstValue("given_name");
string lastName = info.Principal.FindFirstValue("family_name");
}
答案 4 :(得分:0)
Google最早将于2019年1月28日开始关闭应用程序的Google+登录。
https://github.com/aspnet/AspNetCore/issues/6486
因此,我们必须对@mtrax接受的答案进行以下更改:
.AddGoogle(o =>
{
o.ClientId = Configuration["Authentication:Google:ClientId"];
o.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
o.UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo";
o.ClaimActions.Clear();
o.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
o.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
o.ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
o.ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name");
o.ClaimActions.MapJsonKey("urn:google:profile", "link");
o.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
o.ClaimActions.MapJsonKey("image", "picture");
});