C# 将authProvider与MS SDK一起用于C中的图形调用#

C# 将authProvider与MS SDK一起用于C中的图形调用#,c#,azure-active-directory,microsoft-graph-api,C#,Azure Active Directory,Microsoft Graph Api,我正在尝试创建一个C#控制台应用程序,以连接到graph API,并从租户处获取AzureAD的用户列表。我已经注册了应用程序,管理员给了我以下信息 租户名称和租户ID 客户端ID(有时也称为应用程序ID) 客户机密 使用sdk时,我需要使用的C#代码如下所示(): 但是,控制台应用程序将作为批处理进程运行,因此根本没有用户交互。因此,为了提供authProvider,我在MS docs网站上发布了以下文章: 我认为出于我的目的,我需要使用“客户端凭证OAuth流”。显示在该URL上的代码。

我正在尝试创建一个C#控制台应用程序,以连接到graph API,并从租户处获取AzureAD的用户列表。我已经注册了应用程序,管理员给了我以下信息

  • 租户名称和租户ID
  • 客户端ID(有时也称为应用程序ID)
  • 客户机密
使用sdk时,我需要使用的C#代码如下所示():

但是,控制台应用程序将作为批处理进程运行,因此根本没有用户交互。因此,为了提供authProvider,我在MS docs网站上发布了以下文章:

我认为出于我的目的,我需要使用“客户端凭证OAuth流”。显示在该URL上的代码。但它也在这里

IConfidentialClientApplication clientApplication = ClientCredentialProvider.CreateClientApplication(clientId, clientCredential);
ClientCredentialProvider authProvider = new ClientCredentialProvider(clientApplication);
问题在于VisualStudio无法识别ClientCredentialProvider类。我不确定要导入哪个程序集。我在顶部使用了以下用法

using Microsoft.Identity.Client;
using Microsoft.IdentityModel.Clients;
using Microsoft.IdentityModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
我对GitHub repos不是很有经验,我使用的是Visual Studio 2015。我会对示例代码感兴趣;我已经找过了,但找不到。MS有一些讲座,但他们使用另一种类型的身份验证提供程序,它以交互方式进行身份验证,这不是我要找的。我希望使用TenantId/ClientId和客户端密码获取令牌。

ClientCredentialProvider是Microsoft.Graph.Auth包的一部分。有关此软件包的更多信息,请访问

请注意,此软件包目前(2019-05-15)处于预览状态,因此您可能需要等待,然后才能在生产应用程序中使用此软件包

或者,以下示例使用(MSAL)直接使用仅应用程序身份验证设置Microsoft Graph SDK:

// The Azure AD tenant ID or a verified domain (e.g. contoso.onmicrosoft.com) 
var tenantId = "{tenant-id-or-domain-name}";

// The client ID of the app registered in Azure AD
var clientId = "{client-id}";

// *Never* include client secrets in source code!
var clientSecret = await GetClientSecretFromKeyVault(); // 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/$tenantId/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 AuthenticationHeaderValue("Bearer", authResult.AccessToken);
        })
    );

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

(请注意,此示例使用的是Microsoft.Identity.Client软件包的最新版本。早期版本(版本3之前)不包括机密的ClientApplicationBuilder。)

如果要在用户之间循环,请使用以下代码替换var用户:

IGraphServiceUsersCollectionPage users = graphServiceClient.Users.Request().GetAsync().Result;
foreach (User user in users)
{
Console.WriteLine("Found user: " + user.Id);
}

谢谢你的回复,菲利普。代码编译得很好,但做的不多。我在最后一行之后添加了一个foreach来迭代用户,但它甚至没有进入foreach行。我一定是做错了什么?@gtrivedi我们需要一些更具体的细节才能提供帮助。你有没有试过设置一个断点并逐步了解发生了什么?是的,我在最后一行放了一个断点。变量用户。。。紧接着,我有了一个foreach(users中的var项){…},编译器存在,甚至没有进入foreach循环。我有相同的行为:在DelegateAuthenticationProvider中成功地获得了令牌,但随后无限次地调用了users请求。但是没有MSAL库对我来说很有用。例如,这对某些人来说可能是一个解决方案,但我想使用Library在做了一些小动作后,我发现了一个问题:graphClient.Me返回404(可能是权限问题)。所以graphServiceClient.Users工作得很好。有可能在代码中得到错误而不是fiddler吗?
IGraphServiceUsersCollectionPage users = graphServiceClient.Users.Request().GetAsync().Result;
foreach (User user in users)
{
Console.WriteLine("Found user: " + user.Id);
}