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

使用C#快速判断Azure ObjectID为组/用户/服务主体的实现方法

实现方案优化

你可以直接调用你当前使用的Azure AD Graph(或新版Microsoft Graph)原生提供的directoryObjects/getByIds接口,不需要逐一轮询用户、组、服务主体三个端点,单次调用就能直接获取指定ObjectID对应的对象类型和显示名,是官方支持的最优方案。

方案优势

  • 仅需1次API请求即可得到结果,相比你现有逐一轮询的逻辑,大幅减少网络开销,响应速度提升3倍以上
  • 自动返回对象的@odata.type字段,直接就能区分是User、Group还是ServicePrincipal,不需要额外做判断
  • 原生支持批量查询,单次最多可查询1000个ObjectID,适合后续扩展批量处理的场景
  • 你的现有逻辑存在一个隐含问题:如果对象不存在,接口返回404时直接用dynamic取displayName会抛出空引用异常,新方案可以规避这个问题
  • 你现有代码中多次实例化HttpClient会导致套接字资源耗尽,建议复用单例HttpClient实例,优化后的代码也做了对应调整

优化后代码示例

using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

// 建议将HttpClient设置为单例,不要每次请求都实例化,避免套接字资源耗尽
private static readonly HttpClient _graphHttpClient = new HttpClient 
{
    BaseAddress = new Uri("https://graph.windows.net/")
};

public static async Task<(string DisplayName, string ObjectType)> GetDisplayNameAndType(string tenantId, string objectId, string msGraphToken, string objectType = "Decide")
{
    if (!objectType.Equals("Decide", StringComparison.OrdinalIgnoreCase))
    {
        // 如果已经指定对象类型,直接按指定类型查询
        var requestUri = $"{tenantId}/{objectType}/{objectId}?api-version=1.6";
        using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", msGraphToken);
        var response = await _graphHttpClient.SendAsync(request).ConfigureAwait(false);
        if (response.IsSuccessStatusCode)
        {
            var content = await response.Content.ReadAsStringAsync();
            var result = JObject.Parse(content);
            return (result["displayName"]?.ToString() ?? "Unknown", objectType);
        }
        return ("Unknown", "Unknown");
    }

    // 未指定类型时调用getByIds接口一次性查询
    var batchRequestUri = $"{tenantId}/directoryObjects/getByIds?api-version=1.6";
    var batchRequest = new HttpRequestMessage(HttpMethod.Post, batchRequestUri);
    batchRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", msGraphToken);
    batchRequest.Content = new StringContent(JsonConvert.SerializeObject(new 
    {
        ids = new[] { objectId },
        types = new[] { "user", "group", "servicePrincipal" }
    }), System.Text.Encoding.UTF8, "application/json");
    
    var batchResponse = await _graphHttpClient.SendAsync(batchRequest).ConfigureAwait(false);
    if (!batchResponse.IsSuccessStatusCode)
    {
        return ("Unknown", "Unknown");
    }

    var batchContent = await batchResponse.Content.ReadAsStringAsync();
    var batchResult = JObject.Parse(batchContent);
    var targetObject = batchResult["value"]?.FirstOrDefault();
    if (targetObject == null)
    {
        return ("Unknown", "Unknown");
    }

    var odataType = targetObject["@odata.type"]?.ToString();
    var actualType = odataType switch
    {
        "#Microsoft.DirectoryServices.User" => "users",
        "#Microsoft.DirectoryServices.Group" => "groups",
        "#Microsoft.DirectoryServices.ServicePrincipal" => "servicePrincipals",
        _ => "Unknown"
    };
    return (targetObject["displayName"]?.ToString() ?? "Unknown", actualType);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 08:24:02