【问题标题】:MS Graph Api is not returning all user information such as mobile phones ,office phonesMS Graph Api 未返回所有用户信息,例如手机、办公电话
【发布时间】:2020-02-20 15:01:44
【问题描述】:

我正在使用下面的代码来获取所有用户信息,例如 DisplayName 、Office 、Manager name 、Office Phones 等。

但对于少数用户,它不返回手机和办公电话信息。

using Microsoft.Graph;
using Microsoft.Identity.Client;
using System;

namespace MSGraphAPI
{
    class Program
    {


        private static string clientId = "XXXXXXXXXX";


        private static string tenantID = "XXXXX";


        private static string objectId = "XXXXX";


        private static string clientSecret = "XXXX";

        static async System.Threading.Tasks.Task Main(string[] args)
        {




            //     IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
            //.Create(clientId)
            //.WithTenantId(tenantID)
            //.WithClientSecret(clientSecret)
            //.Build();

            //        ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);

            //        GraphServiceClient graphClient = new GraphServiceClient(authProvider);

            //        var users = await graphClient.Users
            //            .Request()
            //            .GetAsync();

            int Flag = 0;
            var tenantId = "XXXXX.onmicrosoft.com";

            // The client ID of the app registered in Azure AD
            var clientId = "XXXX";

            // *Never* include client secrets in source code!
            var clientSecret = "XXXXX"; // Or some other secure place.

            // The app registration should be configured to require access to permissions
            // sufficient for the Microsoft Graph API calls the app will be making, and
            // those permissions should be granted by a tenant administrator.
             var scopes = new string[] { "https://graph.microsoft.com/.default" };


            // Configure the MSAL client as a confidential client
            var confidentialClient = ConfidentialClientApplicationBuilder
                .Create(clientId)
                .WithAuthority($"https://login.microsoftonline.com/XXXX.onmicrosoft.com/v2.0")
                .WithClientSecret(clientSecret)
                .Build();

            // Build the Microsoft Graph client. As the authentication provider, set an async lambda
            // which uses the MSAL client to obtain an app-only access token to Microsoft Graph,
            // and inserts this access token in the Authorization header of each API request. 
            GraphServiceClient graphServiceClient =
                new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {

        // Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
        var authResult = await confidentialClient
            .AcquireTokenForClient(scopes)
            .ExecuteAsync();

        // Add the access token in the Authorization header of the API request.
        requestMessage.Headers.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
                })
                );

            // Make a Microsoft Graph API query
            var users = await graphServiceClient.Users.Request().GetAsync();


            // var groups = await graphServiceClient.Groups.Request().GetAsync();

            //   IGraphServiceUsersCollectionPage userss = await graphServiceClient.Users.Request().GetAsync();




            do
            {
                        foreach (User user in users)
                        {




                            Console.WriteLine(user.DisplayName);
                            Console.WriteLine(user.BusinessPhones);
                            Console.WriteLine(user.MobilePhone);



                           // Console.WriteLine($"{user.Id}");
                            Flag++;
                        }
                    }
                    while (users.NextPageRequest != null && (users = await users.NextPageRequest.GetAsync()).Count > 0);

                    Console.WriteLine("------");


            Console.WriteLine(Flag);
        }
    }
}

我尝试过以下范围:

var scopes = new string[] { "https://graph.microsoft.com/User.ReadWrite.All"};

但是,这会引发异常:

MsalServiceException:AADSTS70011:提供的请求必须包含“范围”输入参数。为输入参数“范围”提供的值无效。范围 https://graph.microsoft.com/User.ReadWrite.All 无效。 跟踪 ID:XXXX-c578-42af-8bd2-7ddd54ee9201

我在 Azure Active Directory 门户中进行了交叉检查,所有用户都配置了商务电话和移动电话。 请帮忙。

【问题讨论】:

    标签: c# azure-active-directory microsoft-graph-api


    【解决方案1】:

    首先你的scope减速不正确。 Microsoft Graph 不支持多个 scope 分配,因为您尝试 分配为格式也不正确的字符串列表。此外 不是scopes 而是scope

    C# 字符串数组中通常声明为List<string>

    您可以尝试以下代码 sn-p,它可以按预期正常工作。

        //Token Request End Point
        string tokenUrl = $"https://login.microsoftonline.com/YourTenant.onmicrosoft.com/oauth2/v2.0/token";
        var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
    
        //I am Using client_credentials as It is mostly recommended
        tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
        {
            ["grant_type"] = "client_credentials",
            ["client_id"] = "b6695c7be-a695-4aea-ad87-e6921e61f659",
            ["client_secret"] = "Vxf1SluKbgu4PF0Nf_Your_Secret_Yp8ns4sc=",
            ["scope"] = "https://graph.microsoft.com/.default" 
        });
    
        dynamic json;
        AccessTokenClass results = new AccessTokenClass();
        HttpClient client = new HttpClient();
    
        var tokenResponse = await client.SendAsync(tokenRequest);
    
        json = await tokenResponse.Content.ReadAsStringAsync();
        results = JsonConvert.DeserializeObject<AccessTokenClass>(json);
    
    
        //New Block For Accessing Data from Microsoft Graph Rest API
        HttpClient _client = new HttpClient();
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format("https://graph.microsoft.com/v1.0/users"));
        //Passing Token For this Request
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
        HttpResponseMessage response = await _client.SendAsync(request);
        //Get User List With Business Phones and Mobile Phones
        dynamic objGpraphUserList = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());
    

    使用的类:

     public class AccessTokenClass
        {
            public string token_type { get; set; }
            public string expires_in { get; set; }
            public string resource { get; set; }
            public string access_token { get; set; }
        }
    

    我收到了这个回复请看下面的截图:

    希望这会对您有所帮助。

    【讨论】:

    • 非常感谢,我已接受,但请帮助我获取所有用户。它只显示 100 个用户。 graph.microsoft.com/v1.0/users?$top=999 提供了 999 个用户,超出了我无法获得的范围,预计有大约 5000 个用户。
    【解决方案2】:

    Microsoft Graph API 以分页格式返回用户,因此要获取下一个用户列表,您必须查询当前响应的 @odata.nextLink 中提到的 url,这将给你下一组用户。

    要实现这一点,您可以运行一个 for 循环,直到 @odata.nextLink 返回 NULL 值。

    更新:

    1. 查询图 api 来获取用户

    2. 使用“@odata.nextLink”查询图形 api 以获取下一组用户。

    【讨论】:

    • 所以,你的意思是当我发出这个请求时,即 HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format("graph.microsoft.com/v1.0/users")); 所以,在下一个循环中我应该通过@ odata.nextLink 到 HttpRequestMessage 请求 = new HttpRequestMessage(HttpMethod.Get, string.Format(@odata.nextLink)); ?
    • 是的,正确。我已经用截图更新了我上面的评论,因为我无法在此处添加截图。请检查一下。如果不清楚,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    相关资源
    最近更新 更多