You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core中使用MicrosoftAccountOptions获取微软账户头像

如何在ASP.NET Core中通过MicrosoftAccountOptions获取微软账户头像

问题概述

我在ASP.NET Core应用中尝试使用MicrosoftAccountOptions获取微软账户头像,已按照外部身份验证指南构建示例应用,微软账户注册流程正常,但使用microsoftOptions.ClaimActions.MapJsonKey("photo", "picture", "url");后,AspNetUsers表并未新增相关列。同时,不清楚如何处理微软Graph中"photo"字段的类型。

当前AspNetUsers表数据示例:

sqlite> SELECT * FROM AspNetUsers;
                  Id = ...
   AccessFailedCount = 0
    ConcurrencyStamp = ...
               Email = ...
      EmailConfirmed = 1
      LockoutEnabled = 1
          LockoutEnd = 
     NormalizedEmail = ...
  NormalizedUserName = ...
        PasswordHash = 
         PhoneNumber = 
PhoneNumberConfirmed = 0
       SecurityStamp = ...
    TwoFactorEnabled = 0
            UserName = ...

相关Program.cs代码:

// ...

services
.AddAuthentication()
.AddMicrosoftAccount(microsoftOptions =>
{
  microsoftOptions.ClientId = configuration["Authentication:Microsoft:ClientId"];
  microsoftOptions.ClientSecret = configuration["Authentication:Microsoft:ClientSecret"];

  //microsoftOptions.ClaimActions.MapJsonKey("photo", "picture", "url");

// ...
});

解决方案

1. 添加必要的权限范围

微软账户默认权限不会返回用户头像信息,需添加User.Read权限获取用户资料:

services.AddAuthentication()
.AddMicrosoftAccount(microsoftOptions =>
{
    microsoftOptions.ClientId = configuration["Authentication:Microsoft:ClientId"];
    microsoftOptions.ClientSecret = configuration["Authentication:Microsoft:ClientSecret"];
    // 添加User.Read权限以获取用户头像
    microsoftOptions.Scope.Add("User.Read");
});

2. 正确映射头像Claim

微软Graph返回的用户头像可通过picture字段获取公开头像URL,修正Claim映射(使用标准Claim类型更规范):

microsoftOptions.ClaimActions.MapJsonKey(ClaimTypes.Photo, "picture", JsonClaimValueTypes.String);

3. 持久化头像信息到AspNetUsers表

默认外部登录的额外Claim不会自动保存到数据库,需手动处理:

步骤1:扩展IdentityUser添加自定义字段

先扩展用户实体类,新增头像URL属性:

public class ApplicationUser : IdentityUser
{
    public string? PhotoUrl { get; set; }
}

更新DbContext使用自定义用户类:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

执行EF迁移更新数据库:

dotnet ef migrations add AddPhotoUrlToUser
dotnet ef database update

步骤2:在外部登录回调中保存头像信息

在处理外部登录的回调方法中,提取头像Claim并保存到用户实体:

var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
    // 处理登录信息获取失败逻辑
}

var photoClaim = info.Principal.FindFirst(ClaimTypes.Photo);
if (photoClaim != null)
{
    var user = await _userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
    if (user != null)
    {
        ((ApplicationUser)user).PhotoUrl = photoClaim.Value;
        await _userManager.UpdateAsync(user);
    }
}

4. 直接获取头像二进制数据(可选)

若需要获取头像的二进制内容,可在OnCreatingTicket事件中调用微软Graph端点获取:

microsoftOptions.Events.OnCreatingTicket = async context =>
{
    var httpClient = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/photo/$value");
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
    
    var response = await httpClient.SendAsync(request);
    if (response.IsSuccessStatusCode)
    {
        var photoBytes = await response.Content.ReadAsByteArrayAsync();
        // 将二进制数据转为Base64字符串存储
        var base64Photo = Convert.ToBase64String(photoBytes);
        context.Identity.AddClaim(new Claim(ClaimTypes.Photo, base64Photo));
    }
};

内容的提问来源于stack exchange,提问作者serdarsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:05:29