从Azure AD获取已登录用户照片的C#示例代码请求
Azure AD旧版Graph获取用户照片的C#实现
前置要求
- 你的Azure AD应用已配置User.Read或User.ReadBasic.All权限(委派权限用于用户登录场景,应用权限用于后台无用户交互场景),且已完成权限同意
- 已获取登录用户的
tenantId(可从Claims的http://schemas.microsoft.com/identity/claims/tenantid字段获取)和userId(http://schemas.microsoft.com/identity/claims/objectidentifier字段)
示例代码
首先安装ADAL NuGet包:
Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
核心实现类
using System; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using Microsoft.IdentityModel.Clients.ActiveDirectory; public class AdGraphPhotoService { // 从应用配置读取以下参数 private readonly string _clientId = "你的应用Client ID"; private readonly string _clientSecret = "你的应用Client Secret"; // 机密客户端时使用 private readonly string _tenantId = "你的租户ID"; private readonly string _graphApiVersion = "2013-11-08"; private readonly string _graphBaseUrl = "https://graph.windows.net"; /// <summary> /// 获取指定用户的照片字节数组 /// </summary> /// <param name="userId">用户Object ID</param> /// <param name="useDelegatedToken">是否使用用户委派的访问令牌(用户已登录场景)</param> /// <param name="userAccessToken">用户登录后的访问令牌(useDelegatedToken为true时必填)</param> /// <returns>照片字节数组,无照片时抛出HttpRequestException</returns> public async Task<byte[]> GetUserPhotoAsync(string userId, bool useDelegatedToken = false, string userAccessToken = null) { AuthenticationResult authResult; var authContext = new AuthenticationContext($"{_graphBaseUrl}/{_tenantId}"); if (useDelegatedToken) { // 委派权限场景:用当前用户的令牌获取Graph访问权限 if (string.IsNullOrEmpty(userAccessToken)) throw new ArgumentException("用户访问令牌不能为空", nameof(userAccessToken)); var userAssertion = new UserAssertion(userAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer"); authResult = await authContext.AcquireTokenAsync( $"{_graphBaseUrl}/.default", new ClientCredential(_clientId), userAssertion); } else { // 应用权限场景:用客户端凭证获取Graph访问权限 var clientCred = new ClientCredential(_clientId, _clientSecret); authResult = await authContext.AcquireTokenAsync( $"{_graphBaseUrl}/.default", clientCred); } // 调用旧版Graph照片端点 using (var httpClient = new HttpClient()) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); var photoEndpoint = $"{_graphBaseUrl}/{_tenantId}/users/{userId}/photo/$value?api-version={_graphApiVersion}"; var response = await httpClient.GetAsync(photoEndpoint); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsByteArrayAsync(); } else { var errorContent = await response.Content.ReadAsStringAsync(); throw new HttpRequestException($"获取照片失败:状态码 {response.StatusCode},详情:{errorContent}"); } } } }
使用示例(ASP.NET MVC场景)
public async Task<ActionResult> UserPhoto() { // 从当前登录用户的Claims获取租户ID和用户ID var tenantId = User.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid")?.Value; var userId = User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value; // 获取用户的访问令牌 var userAccessToken = Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); var photoService = new AdGraphPhotoService(); try { var photoBytes = await photoService.GetUserPhotoAsync(userId, true, userAccessToken); return File(photoBytes, "image/jpeg"); } catch (HttpRequestException ex) { // 处理无照片或权限错误 return Content("无法获取用户照片:" + ex.Message); } }
关键注意点
- 若返回404状态码,说明该用户未在Azure AD中上传照片
- 应用权限需要管理员在Azure AD门户中完成权限同意
- 委派权限场景下,确保用户登录时的scope包含
User.Read或等效权限
内容的提问来源于stack exchange,提问作者Nandha
相关产品推荐
相关产品推荐

