【问题标题】:How to call Microsoft Graph from console application c#如何从控制台应用程序 c# 调用 Microsoft Graph
【发布时间】:2017-12-14 07:21:23
【问题描述】:

我需要调用 Microsoft Graph API 在 Azure AD 中创建用户。

首先我需要从控制台应用程序进行测试,然后需要在 Azure 功能中实现。

https://developer.microsoft.com/en-us/graph/graph-explorer

我是 Microsoft Graph API 的新手,如何从 c# 控制台应用程序连接和执行 API。

我已经在 AAD 中注册了应用程序。

我正在尝试获取令牌:

string resourceId = "https://graph.microsoft.com";
string tenantId = "<tenantID>";
string authString = "https://login.microsoftonline.com/" + tenantId;
string upn = String.Empty;
string clientId = "<ClientID>";
string clientSecret = "<clientSecret>";
//string clientSecret = ConfigurationManager.AppSettings["clientSecret"];


log.Verbose("ClientSecret=" + clientSecret);
log.Verbose("authString=" + authString);

var authenticationContext = new AuthenticationContext(authString, false);

// Config for OAuth client credentials 
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resourceId,clientCred);
string token = authenticationResult.AccessToken;
log.Verbose("token=" + token);

我尝试使用现有的 AADB2C。 b2c 扩展应用程序。不要修改。由 AADB2C 用于存储用户数据。

我已启用以下权限:

我既没有得到异常也没有得到访问令牌,程序静默退出

还有:

有新的图书馆

 <package id="Microsoft.Identity.Client" version="1.1.0-preview" targetFramework="net46" />

如何在没有登录弹出窗口的情况下直接登录并获取令牌? 公共客户端应用程序

【问题讨论】:

标签: azure microsoft-graph-api


【解决方案1】:

为了从控制台应用程序连接,您需要首先获得一个有效的令牌。由于您缺少 UI,因此您需要 Get access without a user请注意,这种类型的“仅限应用”令牌需要 Administrative Consent 才能使用。

为了支持Create User 方案,您需要确保您的permission scopes 包含User.ReadWrite.All

一旦您拥有一个有效的令牌,您就可以调用 Graph API。 Graph 是一个 REST API,因此所有调用都是通过 HTTP 进行的,令牌在 Authorization Header 中传递。

您可以在Get started with Microsoft Graph and REST 阅读一般概述。还有几种可用的语言/框架特定概述,但它们都假设您有一个 UI(即不仅仅是控制台)。一般来说,如果您正在寻找用于创建用户的控制台工具,您可能更喜欢使用PowerShell

【讨论】:

  • 您的评论一定为我节省了一天的工作时间,至少!谢谢你,马克。
【解决方案2】:

我假设你已经拥有获得行政许可的 Azure AD 应用程序。

为了从控制台应用程序连接,您需要首先获得一个有效的令牌。由于您缺少 UI,因此您需要在没有用户的情况下获取访问权限。请注意,这种类型的“仅限应用”令牌需要获得管理同意才能使用。

然后你必须在你的dotnet 项目中添加两个NuGet 依赖项

<PackageReference Include="Microsoft.Graph" Version="1.15.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.0.0" />

Microsoft.Identity.Client 用于使用 Azure AD 进行身份验证,Microsoft.Graph 用于执行 MS Graph 查询。

var tenantId = "you-azure-tenand-id";
var clientId = "azure-ad-application-id";
var clientSecret = "unique-secret-generated-for-this-console-app";

// Configure app builder
var authority = $"https://login.microsoftonline.com/{tenantId}";
var app = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithClientSecret(clientSecret)
    .WithAuthority(new Uri(authority))
    .Build(); 

// Acquire tokens for Graph API
var scopes = new[] {"https://graph.microsoft.com/.default"};
var authenticationResult = await app.AcquireTokenForClient(scopes).ExecuteAsync();

// Create GraphClient and attach auth header to all request (acquired on previous step)
var graphClient = new GraphServiceClient(
    new DelegateAuthenticationProvider(requestMessage => {
        requestMessage.Headers.Authorization = 
            new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);

        return Task.FromResult(0);
    }));

// Call Graph API
var user = await graphClient.Users["Me@domain.com"].Request().GetAsync()

2020.01 更新

有一个新包Microsoft.Graph.Auth 可以简化身份验证和令牌管理。

假设您这次想使用一些 Beta API。

<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.2" />
<PackageReference Include="Microsoft.Graph.Beta" Version="0.12.0-preview" />
var tenantId = "you-azure-tenand-id";
var clientId = "azure-ad-application-id";
var clientSecret = "unique-secret-generated-for-this-console-app";

// Configure application
var clientApplication = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantId)
    .WithClientSecret(clientSecret)
    .Build();

// Create ClientCredentialProvider that will manage auth token for you
var authenticationProvider = new ClientCredentialProvider(clientApplication);
var graphClient = new GraphServiceClient(authenticationProvider);

// Call Graph API
var user = await graphClient.Users["Me@domain.com"].Request().GetAsync()

【讨论】:

  • 感谢这个帮助我的答案。但是有一个问题:如何通过最后一个解决方案传递范围?
  • @Jerome2606 为什么要使用客户端凭据身份验证指定范围?为 AAD 应用程序指定范围(即限制您的应用程序的访问权限),您以应用程序(无用户)身份进行身份验证以获取具有为应用程序指定的范围的令牌。出于某种原因,您想进一步减少访问权限?其他IAuthenticationProvider 接受范围作为参数github.com/microsoftgraph/msgraph-sdk-dotnet-auth
  • 我明白了,你的回答对我帮助很大:)。我正在考虑使用我习惯使用的身份进行身份验证。我正在 Azure 界面中配置访问权限。
  • @SergeyTihon 嗨,代码现在可以工作了吗?出现异常是正常的:代码:generalException 消息:验证请求时发生意外异常。
  • @Sanpas 是的,第一个样本应该可以工作。第二个只有 Microsoft.Graph Microsoft.Graph.Auth 尚不兼容Microsoft.Graph.Core v2.0 (Microsoft.Graph.Auth v4.0)
【解决方案3】:

这个问题相当老了,但是当我最初需要做同样的事情时,它是第一个出现的问题。下面我将记录我用来实现它的步骤和资源:

  1. 我使用了 O365 租户(您可以从 office.com 获得一个 - 请注意,您可以获得一年的开发人员试用期)。拥有租户后,如果您以租户管理员用户身份登录,您还可以访问 Azure 门户。在 Azure 门户下,转到 Active Directory/properties 以查看租户 ID。
  2. 我按照https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-netcore-daemon 此处的说明创建了一个新的注册应用程序。我创建了一个新密码并复制了该值(这将是您控制台应用程序中的客户端密码)。注册的应用程序 ID 将是您控制台应用程序中的客户端 ID。
  3. 我克隆了上述链接中的 github 存储库,并将 appsettings 中的值更改为上述步骤中记录的租户 ID、客户端 ID 和客户端密码。
  4. 该存储库中的代码有一些调用的方法,这些方法在 .NETCore 2.1 中不再存在于 ConfigurationBuilder 中。我替换了这些行(可能有更好/更短的方法):

    authenticationConfig.Tenant = Configuration.GetSection("Tenant").Value.ToString(); authenticationConfig.ClientId = Configuration.GetSection("ClientId").Value.ToString(); authenticationConfig.ClientSecret = Configuration.GetSection("ClientSecret").Value.ToString();

  5. 您现在应该遍历租户中的用户。您可以转到图形资源管理器 (https://developer.microsoft.com/en-us/graph/graph-explorer) 来查找更多 URL(在 Program.cs 中找到行来替换它们)。据我所知,API 的 v2.0 是“beta”(将“beta”放在“v1.0”所在的位置 - 如果我错了,请有人纠正我)。

    等待 apiCaller.CallWebApiAndProcessResultASync("https://graph.microsoft.com/v1.0/users", result.AccessToken, Display);

【讨论】:

  • 我还必须使用 Nuget 包管理来安装这些包(版本以防万一): Microsoft.Extension.Configuration (2.2.0) Microsoft.Extension.Configuration.Json (2.2.0 ) Microsoft.Identity.Client(2.7.0)
【解决方案4】:

MSAL console app tutorial 描述了在 .NET 控制台应用程序中使用 MSAL(Microsoft 身份验证库)获取令牌。

为了进行 Microsoft Graph 调用,我用它替换了 RunAsync() 函数,它将获取的令牌附加到带有 GraphServiceClient 的请求:

static async Task RunAsync()
    {
        const string clientId = "your client id";
        string[] scopes = { "User.Read" };
        AuthenticationResult result;

        var clientApp = new PublicClientApplication(clientId);
        try
        {
            result = await clientApp.AcquireTokenAsync(scopes.Split(new char[] { ' ' }));
            Console.WriteLine(result.AccessToken);
            GraphServiceClient graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    async (requestMessage) =>
                    {
                        // Append the access token to the request.
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);

                        // Some identifying header
                        requestMessage.Headers.Add("SampleID", "aspnet-connect-sample");
                    }));

            // Get a page of mail from the inbox
            var inboxMail = await graphClient.Me.MailFolders.Inbox.Messages.Request().GetAsync();
            foreach(var mail in inboxMail.CurrentPage.ToList())
            {
                Console.Write("From: {0}\nSubject: {1}\nBody:\n{2}\n--------------------\n", mail.From.EmailAddress.Address, mail.Subject, mail.BodyPreview);
            }
        }

        // Unable to retrieve the access token silently.
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

【讨论】:

  • 登录屏幕异常:我们无法完成您的请求 Microsoft 帐户遇到技术问题。请稍后再试。
【解决方案5】:

注意

您必须使用 Azure AD Graph API 来管理 Azure AD B2C 中的用户 目录。这与 Microsoft Graph API 不同。了解更多 here.

有一个很好的示例项目@GitHub:AzureADQuickStarts/B2C-GraphAPI-DotNet,它的随附文档here

【讨论】:

    猜你喜欢
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多