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

技术问询:通过Graph API从Azure AD获取用户并转为带全属性的C#列表

获取Azure AD所有用户及全部属性的C#实现方案

我来给你整理两个可行的实现方案,一个是用官方推荐的Microsoft Graph SDK(代码更简洁易维护),另一个是直接发送HTTP请求(适合不想依赖SDK的场景),都能满足你获取所有用户及全部属性的需求:

前置准备工作

在写代码之前,你需要先在Azure AD中完成应用注册:

  • 登录Azure门户,注册一个应用程序(选择“帐户类型”为“仅限此组织目录中的帐户”)
  • 为该应用添加应用权限:搜索并添加Directory.Read.All权限,然后点击“授予管理员同意”(必须完成这一步,否则无法获取所有用户)
  • 记录下三个关键信息:租户ID、客户端ID、客户端密钥(在应用的“证书和密码”页面生成)

方案一:使用Microsoft Graph SDK(推荐)

这个方案依赖官方SDK,无需手动处理令牌和分页逻辑,代码更简洁。

1. 安装NuGet包

在你的C#项目中安装两个NuGet包:

Install-Package Microsoft.Graph
Install-Package Azure.Identity

2. 完整代码示例

using Microsoft.Graph;
using Azure.Identity;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using System.Text.Json;

namespace AzureADUserExport
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // 替换为你的Azure AD信息
            string tenantId = "你的租户ID";
            string clientId = "你的应用客户端ID";
            string clientSecret = "你的应用客户端密钥";

            // 创建身份验证凭据
            var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);

            // 初始化Graph服务客户端
            var graphClient = new GraphServiceClient(credential);

            // 存储所有用户的列表
            List<User> allUsers = new List<User>();

            // 第一次请求用户数据,指定$select=*获取全部属性
            var usersPage = await graphClient.Users
                .Request()
                .Select("*") // 关键:必须添加这个才能获取所有属性,否则只返回默认属性
                .GetAsync();

            allUsers.AddRange(usersPage.CurrentPage);

            // 处理分页:如果用户数量超过100,Graph会分页返回,需要循环获取所有页
            while (usersPage.NextPageRequest != null)
            {
                usersPage = await usersPage.NextPageRequest.GetAsync();
                allUsers.AddRange(usersPage.CurrentPage);
            }

            // 转换为JSON并保存到文件
            string jsonOutput = JsonSerializer.Serialize(allUsers, new JsonSerializerOptions { WriteIndented = true });
            System.IO.File.WriteAllText("AzureAD_AllUsers.json", jsonOutput);

            // 输出结果统计
            Console.WriteLine($"成功导出 {allUsers.Count} 个用户,已保存到AzureAD_AllUsers.json");
        }
    }
}

方案二:直接HTTP请求调用Graph API

如果你不想依赖SDK,可以直接通过HttpClient发送请求,手动处理令牌和分页。

完整代码示例

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace AzureADUserExportHttp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // 替换为你的Azure AD信息
            string tenantId = "你的租户ID";
            string clientId = "你的应用客户端ID";
            string clientSecret = "你的应用客户端密钥";

            // 第一步:获取访问令牌
            string tokenUrl = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
            var tokenRequestContent = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("client_id", clientId),
                new KeyValuePair<string, string>("client_secret", clientSecret),
                new KeyValuePair<string, string>("grant_type", "client_credentials"),
                new KeyValuePair<string, string>("scope", "https://graph.microsoft.com/.default")
            });

            using var httpClient = new HttpClient();
            var tokenResponse = await httpClient.PostAsync(tokenUrl, tokenRequestContent);
            tokenResponse.EnsureSuccessStatusCode(); // 确保令牌获取成功

            var tokenData = JsonSerializer.Deserialize<TokenResponse>(await tokenResponse.Content.ReadAsStringAsync());
            string accessToken = tokenData.access_token;

            // 第二步:循环获取所有用户(处理分页)
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            List<JsonElement> allUsers = new List<JsonElement>();
            string nextRequestUrl = "https://graph.microsoft.com/v1.0/users?$select=*";

            while (!string.IsNullOrEmpty(nextRequestUrl))
            {
                var userResponse = await httpClient.GetAsync(nextRequestUrl);
                userResponse.EnsureSuccessStatusCode();

                var userData = JsonSerializer.Deserialize<UserListResponse>(await userResponse.Content.ReadAsStringAsync());
                allUsers.AddRange(userData.value);

                // 更新下一页的请求地址
                nextRequestUrl = userData.OdataNextLink;
            }

            // 转换为JSON并保存
            string jsonOutput = JsonSerializer.Serialize(allUsers, new JsonSerializerOptions { WriteIndented = true });
            System.IO.File.WriteAllText("AzureAD_AllUsers_Http.json", jsonOutput);

            Console.WriteLine($"成功导出 {allUsers.Count} 个用户,已保存到AzureAD_AllUsers_Http.json");
        }

        // 用于反序列化令牌响应的模型类
        private class TokenResponse
        {
            public string access_token { get; set; }
            public string token_type { get; set; }
        }

        // 用于反序列化用户列表响应的模型类
        private class UserListResponse
        {
            public List<JsonElement> value { get; set; }
            [JsonPropertyName("@odata.nextLink")]
            public string OdataNextLink { get; set; }
        }
    }
}

关键注意事项

  1. 权限必须正确配置:一定要给应用添加Directory.Read.All的应用权限并完成管理员同意,否则会返回权限不足的错误
  2. 必须指定$select=*:Graph API默认只返回约20个常用属性,只有添加$select=*才能获取用户的全部属性
  3. 处理分页:当组织内用户超过100个时,Graph API会分页返回结果,必须通过@odata.nextLink循环获取所有页的数据
  4. 敏感属性:部分敏感属性(如userPrincipalName之外的身份信息)可能需要额外的权限,如果遇到属性缺失,可以检查Azure AD的权限配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:25:02