【问题标题】:Microsoft.Graph C#: Make an API request programmaticallyMicrosoft.Graph C#:以编程方式发出 API 请求
【发布时间】:2022-11-09 07:16:21
【问题描述】:

我正在使用 Microsoft.Graph SDK,我需要在类库中以编程方式获取电子邮件 SentItems。

我正在使用以下代码创建客户端:

private static Graph.GraphServiceClient CreateClient()
{
    var scopes = new[] { "User.Read" };

    // Multi-tenant apps can use "common",
    // single-tenant apps must use the tenant ID from the Azure portal
    var tenantId = "xxx";

    // Value from app registration
    var clientId = "xxxx";

    var pca = Microsoft.Identity.Client.PublicClientApplicationBuilder
        .Create(clientId)
        .WithTenantId(tenantId)
        .Build();

    // DelegateAuthenticationProvider is a simple auth provider implementation
    // that allows you to define an async function to retrieve a token
    // Alternatively, you can create a class that implements IAuthenticationProvider
    // for more complex scenarios
    var authProvider = new Graph.DelegateAuthenticationProvider(async (request) =>
    {
        // Use Microsoft.Identity.Client to retrieve token
        var result = await pca.AcquireTokenByIntegratedWindowsAuth(scopes).ExecuteAsync();

        request.Headers.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
    });

    return new Graph.GraphServiceClient(authProvider);
}

然后我试图用下一个方式使用客户端:

var sentEmails = graphClient.Users[authMail].MailFolders.SentItems.Request().GetAsync().Result;

但是在执行请求时出现以下异常:

抛出异常:“Microsoft.Identity.Client.MsalUiRequiredException” 在 System.Private.CoreLib.dll 抛出异常: System.Private.CoreLib.dll 中的“System.AggregateException”

我认为另一种选择可能是获取身份验证令牌。我可以使用以下代码获取身份验证令牌:

private static async Task<string> GetGraphToken()
{
    var resource = "https://graph.microsoft.com/";
    var instance = "https://login.microsoftonline.com/";
    var tenant = "xxx";
    var clientID = "xxxx";
    var secret = "xxxxx";
    var authority = $"{instance}{tenant}";
    var authContext = new AuthenticationContext(authority);
    var credentials = new ClientCredential(clientID, secret);
    var authResult = authContext.AcquireTokenAsync(resource, credentials).Result;
    return authResult.AccessToken;
}

它可以正常工作,但是我不知道如何使用它以编程方式执行 API 请求。

这两种变体中的任何一种对我来说都可以,在第一种情况下摆脱异常,或者在第二种情况下找到使用令牌进行编程 SDK API 调用的方法。

接下来我可以尝试什么?

编辑 1

我正在尝试下一种方法,但抛出了相同的异常:

var accessToken = GetToken();

var client = new Graph.GraphServiceClient(
    new Graph.DelegateAuthenticationProvider(
        (requestMessage) =>
        {
            requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
            return Task.FromResult(0);
        }));
        
var mails = client.Users[authMail].MailFolders.SentItems.Messages.Request().GetAsync().Result;

【问题讨论】:

    标签: c# microsoft-graph-api asp.net-core-webapi token


    【解决方案1】:

    请前往 api 文档查看所需的 api 权限。例如,对于应用程序类型,this api 需要 Mail.ReadBasic.All, Mail.Read, Mail.ReadWrite。我的代码示例需要使用应用程序类型的 api 权限。

    请同意 api 权限并尝试以下代码:

    using Microsoft.Graph;
    using Azure.Identity;
    
    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var tenantId = "tenant_name.onmicrosoft.com";
    var clientId = "aad_app_id";
    var clientSecret = "client_secret";
    var clientSecretCredential = new ClientSecretCredential(
                    tenantId, clientId, clientSecret);
    var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
    var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
    var res = await graphClient.Users["{user-id}"].MailFolders.SentItems.Request().GetAsync();
    

    【讨论】:

    • 感谢您的回复@Tiny Wang。您能否让我知道在您的屏幕截图中访问该 API 权限配置资源的 URL?我无法访问我们的 Azure 门户,需要询问我的技术主管,但不知道具体在哪里。
    • 打开 azure 门户 -> 转到 azure 活动目录 -> 应用注册刀片 -> 选择您使用的 azure 广告应用程序 -> API 权限刀片 -> 添加权限 -> 选择 Microsoft graph api -> 选择应用程序权限 -> 找到您需要的权限并选择它们->单击添加权限按钮->单击授予xxx管理员同意
    • @TinyWang Azure 门户中的哪个位置可以配置 Azure 应用程序可以访问的电子邮件帐户?
    • 如果您授予应用程序 api 权限,则可以通过此 aad 应用程序访问租户中的每个电子邮件地址。您不能设置某些被拒绝访问的电子邮件地址。
    • 非常感谢@Tiny Wang 的详细回复和解释。我的问题最终是我没有访问 AZ 门户的权限。现在,我公司的支持人员为我提供了所需的权限,一切正常。
    【解决方案2】:

    在您的第一个示例中,您尝试使用 IWA auth https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token-integrated-windows-authentication?tabs=dotnet 并且由于需要交互而失败。这很可能是由于帐户上启用了 MFA,通常您不想禁用 MFA,因此您需要处理交互并执行其他因素或使用其他方法。您也没有正确的电子邮件范围,例如 Mail.Read 将需要

    在第二种方法中,您使用客户端凭据流程(但较旧的 v1 流程),但如果您想使用 Graph SDK,只需执行 https://learn.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS#client-credentials-provider 就更容易,但请确保您在应用注册中拥有正确的权限并确保它已同意。

    【讨论】:

    • 非常感谢您对@Glen Scales 的详细回复。结果是我没有访问 AZ 门户的权限。现在,我公司的支持人员为我提供了所需的权限,一切都运行良好,但您的链接无论如何都非常有帮助。
    猜你喜欢
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多