【问题标题】:Unable to send email via Microsoft Graph API with Delegated Permission无法通过具有委派权限的 Microsoft Graph API 发送电子邮件
【发布时间】:2021-01-28 10:06:33
【问题描述】:

我创建了一个 C# 控制台应用程序来使用 Microsoft Graph API 发送电子邮件。添加 Mail.Send Application 权限后,它工作正常。但是,由于公司的要求,我被要求使用 Mail.Send Delegated 权限,而使用该权限我看不到它工作,我看到这个错误:

在添加 Mail.Send Delegated 权限后,我应该考虑执行哪些步骤才能使其正常工作?

这是我的代码:

    static void Main(string[] args)
    {
        // Azure AD APP
        string clientId = "<client Key Here>";
        string tenantID = "<tenant key here>";
        string clientSecret = "<client secret here>";

        Task<GraphServiceClient> callTask = Task.Run(() => SendEmail(clientId, tenantID, clientSecret));
        // Wait for it to finish
        callTask.Wait();
        // Get the result
        var astr = callTask;
    }

    public static async Task<GraphServiceClient> SendEmail(string clientId, string tenantID, string clientSecret)
    {

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

        var authProvider = new ClientCredentialProvider(confidentialClientApplication);       

        var graphClient = new GraphServiceClient(authProvider);

        var message = new Message
            {
                Subject = subject,
                Body = new ItemBody
                {
                    ContentType = BodyType.Text,
                    Content = content
                },
                ToRecipients = new List<Recipient>()
                {
                    new Recipient
                    {
                        EmailAddress = new EmailAddress { Address = recipientAddress }
                    }
                }
            };

         var saveToSentItems = true;

         await _graphClient.Users[<userprincipalname>]
                                .SendMail(message, saveToSentItems)
                                .Request()
                                .PostAsync();

        return graphClient;

    }

更新:

根据下面的回答,我更新代码如下:

var publicClientApplication = PublicClientApplicationBuilder
            .Create("<client-id>")
            .WithTenantId("<tenant-id>")
            .Build();

            var authProvider = new UsernamePasswordProvider(publicClientApplication);

var secureString = new NetworkCredential("", "<password>").SecurePassword;

User me = await graphClient.Me.Request()
                .WithUsernamePassword("<username>", secureString)
                .GetAsync();

我启用了“允许公共客户端流”来修复异常。

现在我看到另一个异常:权限不足,无法完成操作。

我错过了什么?

更新:目前我看到这个异常,代码没有变化:

【问题讨论】:

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


    【解决方案1】:

    您提供的代码显示您使用client credential flow 进行身份验证。当您使用Mail.Send 应用程序权限时,使用客户端凭据流是可以的。但是如果你使用Mail.SendDelegated 权限,我们就不能使用客户端凭据。您应该使用username/password flow 进行身份验证。

    ==================================更新====== ==============================

    下面是我的代码:

    using Microsoft.Graph;
    using Microsoft.Graph.Auth;
    using Microsoft.Identity.Client;
    using System;
    using System.Collections.Generic;
    using System.Security;
    
    namespace ConsoleApp34
    {
        class Program
        {
            static async System.Threading.Tasks.Task Main(string[] args)
            {
                Console.WriteLine("Hello World!");
    
                var publicClientApplication = PublicClientApplicationBuilder
                .Create("client id")
                .WithTenantId("tenant id")
                .Build();
    
                string[] scopes = new string[] { "mail.send" };
    
                UsernamePasswordProvider authProvider = new UsernamePasswordProvider(publicClientApplication, scopes);
    
                GraphServiceClient graphClient = new GraphServiceClient(authProvider);
    
                var message = new Message
                {
                    Subject = "Meet for lunch?",
                    Body = new ItemBody
                    {
                        ContentType = BodyType.Text,
                        Content = "The new cafeteria is open."
                    },
                    ToRecipients = new List<Recipient>()
                    {
                        new Recipient
                        {
                            EmailAddress = new EmailAddress
                            {
                                Address = "to email address"
                            }
                        }
                    }
                };
    
                var securePassword = new SecureString();
                foreach (char c in "your password")
                    securePassword.AppendChar(c);
    
                var saveToSentItems = true;
    
                await graphClient.Me
                        .SendMail(message, saveToSentItems)
                        .Request().WithUsernamePassword("your email", securePassword)
                        .PostAsync();
            }
        }
    }
    

    您的错误消息Insufficient privileges to complete the operation的原因是您使用了代码:

    User me = await graphClient.Me.Request()
                    .WithUsernamePassword("<username>", secureString)
                    .GetAsync();
    

    此代码用于获取用户(我)的信息但不发送电子邮件,您尚未将权限添加到应用程序。所以它会显示Insufficient privileges to complete the operation。请删除此代码并改用我的代码中的代码块:

    await graphClient.Me.SendMail(message, saveToSentItems)
                        .Request().WithUsernamePassword("your email", securePassword)
                        .PostAsync();
    

    ===============================Update2========= =============================

    【讨论】:

    • 谢谢!我按照您的建议更新了代码,但我看到了一个异常。请查看我更新的问题。
    • 嗨@user989988 请参阅我的回答中的“更新”。
    • 谢谢。我会试试你的代码。快速提问 - 是否可以使用委派权限发送邮件而无需在代码中提供用户密码?请告诉我。
    • @user989988 恐怕不会。如果您使用委派权限,则无论您使用何种流程(用户名/密码流程、身份验证代码流程......),都必须提供密码。
    • @user989988 我在回答中的“Update2”下提供了我注册应用的两张截图供您参考。
    猜你喜欢
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多