C# 使用带有razor页面的.Net Core v3登录后显示Google图片

C# 使用带有razor页面的.Net Core v3登录后显示Google图片,c#,razor,blazor,.net-core-3.0,C#,Razor,Blazor,.net Core 3.0,我正在使用Blazor和.NETCoreV3构建一个新的应用程序 作为身份验证,我想使用我们的Google G套件 我成功地登录了,但我很难找到要显示在标题中的个人资料图片 这是我的Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options =>

我正在使用Blazor和.NETCoreV3构建一个新的应用程序

作为身份验证,我想使用我们的Google G套件

我成功地登录了,但我很难找到要显示在标题中的个人资料图片

这是我的Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();
        services.AddRazorPages();

        services.AddAuthentication()
            .AddGoogle("Google", options =>
            {
                IConfigurationSection googleAuthNSection =
                    Configuration.GetSection("Authentication:Google");

                options.ClientId = googleAuthNSection["ClientId"];
                options.ClientSecret = googleAuthNSection["ClientSecret"];

                options.UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo";
                options.ClaimActions.Clear();
                options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
                options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
                options.ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
                options.ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name");
                options.ClaimActions.MapJsonKey("urn:google:profile", "link");
                options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
                options.ClaimActions.MapJsonKey("image", "picture");

                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = context =>
                    {                            
                        var myProfile = JsonSerializer.Deserialize<Dictionary<string, object>>(context.User.ToString());

                        if (myProfile.ContainsKey("picture"))
                        {
                            var identity = (ClaimsIdentity)context.Principal.Identity;
                            identity.AddClaim(new Claim("picture", myProfile["picture"].ToString()));
                        }
                        return Task.CompletedTask;
                    }
                };
            });
    }
更新
myProfile
包含:

[0]: {[id, ValueKind = String : "1095252652..."]}
[1]: {[email, ValueKind = String : "paul..."]}
[2]: {[verified_email, ValueKind = True : "True"]}
[3]: {[name, ValueKind = String : "Paul.."]}
[4]: {[given_name, ValueKind = String : "Paul"]}
[5]: {[family_name, ValueKind = String : ".."]}
[6]: {[picture, ValueKind = String : "https://lh3.googleusercontent.com/a-/A..."]}
[7]: {[locale, ValueKind = String : "nl"]}
[8]: {[hd, ValueKind = String : "..."]}

本文展示了有效的代码:

startup.cs的此更改可能是您所需要的:

        services.AddAuthentication().AddGoogle(options =>
        {
            options.ClientId = Configuration["Google:ClientId"];
            options.ClientSecret = Configuration["Google:ClientSecret"];
            options.ClaimActions.MapJsonKey("urn:google:profile", "link");
            options.ClaimActions.MapJsonKey("urn:google:image", "picture");
        });
您可以使用.razor控件显示图像,如下所示:

@using System.Security.Claims
@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor _httpContextAccessor
@inject HttpClient Http
@if (User.Identity.Name != null)
{
    <img src="@Avatar" />
    <b>You are logged in as: @GivenName @Surname</b>
    <a class="ml-md-auto btn btn-primary"
       href="/Logout"
       target="_top">Logout</a>
}
else
{
    <a class="ml-md-auto btn btn-primary"
       href="/Login"
       target="_top">Login</a>
}
@code {
    private ClaimsPrincipal User;
    private string GivenName;
    private string Surname;
    private string Avatar;
    protected override void OnInitialized()
    {
        base.OnInitialized();
        try
        {
            // Set the user to determine if they are logged in
            User = _httpContextAccessor.HttpContext.User;
            // Try to get the GivenName
            var givenName =
                _httpContextAccessor.HttpContext.User
                .FindFirst(ClaimTypes.GivenName);
            if (givenName != null)
            {
                GivenName = givenName.Value;
            }
            else
            {
                GivenName = User.Identity.Name;
            }
            // Try to get the Surname
            var surname =
                _httpContextAccessor.HttpContext.User
                .FindFirst(ClaimTypes.Surname);
            if (surname != null)
            {
                Surname = surname.Value;
            }
            else
            {
                Surname = "";
            }
            // Try to get Avatar
            var avatar =
            _httpContextAccessor.HttpContext.User
            .FindFirst("urn:google:image");
            if (avatar != null)
            {
                Avatar = avatar.Value;
            }
            else
            {
                Avatar = "";
            }
        }
        catch { }
    }
}
@使用System.Security.Claims
@使用Microsoft.AspNetCore.Http
@注入IHttpContextAccessor\u httpContextAccessor
@注入HttpClient Http
@if(User.Identity.Name!=null)
{
您是以@GivenName@姓氏登录的
}
其他的
{
}
@代码{
私人用户;
私人字符串GivenName;
私家姓;
私有字符串化身;
受保护的覆盖无效OnInitialized()
{
base.OnInitialized();
尝试
{
//设置用户以确定他们是否已登录
User=\u httpContextAccessor.HttpContext.User;
//试着给我一个礼物
var Givename=
_httpContextAccessor.HttpContext.User
.FindFirst(ClaimTypes.GivenName);
if(givenName!=null)
{
GivenName=GivenName.Value;
}
其他的
{
GivenName=User.Identity.Name;
}
//试着查一下姓氏
姓=
_httpContextAccessor.HttpContext.User
.FindFirst(索赔类型.姓氏);
if(姓氏!=null)
{
姓氏=姓氏。值;
}
其他的
{
姓氏=”;
}
//试着得到阿凡达
虚拟化身=
_httpContextAccessor.HttpContext.User
.FindFirst(“urn:google:image”);
如果(化身!=null)
{
阿凡达=阿凡达值;
}
其他的
{
阿凡达=”;
}
}
捕获{}
}
}

您将
图像
映射到
图片
,但在
OnCreatingTicket
中测试图片。您是否尝试测试
图像
?(
if(myProfile.ContainsKey(“image”))
)谢谢@aguafrommars。我已经添加了myProfile字典的输出。如您所见,“picture”具有正确的值。当我看到
identity.Claims
时,我有6个声明,包括名字和图片。但是我不知道如何在我的登录页面中阅读这些声明。我的问题是你的
OnCreatingTicket
delegate,你应该在
上下文中添加声明。Identity
你的意思是我应该像
context.Identity.AddClaim那样添加声明(新声明(“图片”,myProfile[“图片”].ToString())
但是我的登录页面中的用户对象仍然没有额外的声明。是的,在一个项目中,这就是我如何使用OAuth Provider设置GitHub身份验证的方法谢谢Michael,你的答案正是我想要的。希望谷歌现在能把它排得更高,因为我希望我能在几周前找到你的网站。嗨,我这里也有一个类似的问题:,有人有什么想法可以帮助我吗@迈克尔·华盛顿?@ClubberLang-我看过你的问题,但我对那种情况没有经验。
        services.AddAuthentication().AddGoogle(options =>
        {
            options.ClientId = Configuration["Google:ClientId"];
            options.ClientSecret = Configuration["Google:ClientSecret"];
            options.ClaimActions.MapJsonKey("urn:google:profile", "link");
            options.ClaimActions.MapJsonKey("urn:google:image", "picture");
        });
@using System.Security.Claims
@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor _httpContextAccessor
@inject HttpClient Http
@if (User.Identity.Name != null)
{
    <img src="@Avatar" />
    <b>You are logged in as: @GivenName @Surname</b>
    <a class="ml-md-auto btn btn-primary"
       href="/Logout"
       target="_top">Logout</a>
}
else
{
    <a class="ml-md-auto btn btn-primary"
       href="/Login"
       target="_top">Login</a>
}
@code {
    private ClaimsPrincipal User;
    private string GivenName;
    private string Surname;
    private string Avatar;
    protected override void OnInitialized()
    {
        base.OnInitialized();
        try
        {
            // Set the user to determine if they are logged in
            User = _httpContextAccessor.HttpContext.User;
            // Try to get the GivenName
            var givenName =
                _httpContextAccessor.HttpContext.User
                .FindFirst(ClaimTypes.GivenName);
            if (givenName != null)
            {
                GivenName = givenName.Value;
            }
            else
            {
                GivenName = User.Identity.Name;
            }
            // Try to get the Surname
            var surname =
                _httpContextAccessor.HttpContext.User
                .FindFirst(ClaimTypes.Surname);
            if (surname != null)
            {
                Surname = surname.Value;
            }
            else
            {
                Surname = "";
            }
            // Try to get Avatar
            var avatar =
            _httpContextAccessor.HttpContext.User
            .FindFirst("urn:google:image");
            if (avatar != null)
            {
                Avatar = avatar.Value;
            }
            else
            {
                Avatar = "";
            }
        }
        catch { }
    }
}