使用带有剃须刀页面的.Net Core v3登录后显示Google图片

问题描述 投票:0回答:1

我正在使用Blazor和.NET Core v3构建新应用程序。

作为身份验证,我想使用我们的Google G Suite。

我设法登录,但是我很难找到个人头像显示在标题中。

这是我的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;
                    }
                };
            });
    }

这是我的_LoginPartial.cshtml

    @if (SignInManager.IsSignedIn(User))
    {
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
        </li>
        <li class="nav-item">
            <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
                <button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
            </form>
        </li>
        @foreach (var claim in User.Claims)
        {
            <span>@claim.Type : @claim.Value</span>
        }
    }

我以为options.ClaimActions.MapJsonKey会填满我的User.Claims。但是在我的foreach中,仅存在4个基本声明。

我知道myProfile["picture"]保留个人资料图片的网址。但是我无法在“登录”页面上获得它。

我已经尝试过:

var info = await SignInManager.GetExternalLoginInfoAsync();
if (info != null)
{
    var avatar = info.Principal.FindFirst("picture");
}

更新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 : "..."]}
c# razor blazor .net-core-3.0
1个回答
0
投票

本文显示了有效的代码:Google Authentication in Server Side Blazor

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 { }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.