Azure active directory 无法通过具有委派权限的Microsoft Graph API发送电子邮件

Azure active directory 无法通过具有委派权限的Microsoft Graph API发送电子邮件,azure-active-directory,microsoft-graph-api,Azure Active Directory,Microsoft Graph Api,我创建了一个C#控制台应用程序,使用Microsoft Graph API发送电子邮件。在添加Mail.Send应用程序权限时,它可以正常工作。但是,由于公司的要求,我被要求使用Mail.SendDelegated权限,而使用该权限时,我看不到它起作用,我看到以下错误: 在添加邮件后,我有什么步骤需要考虑吗?发送委派< /强>权限以使其生效? 这是我的密码: static void Main(string[] args) { // Azure AD APP

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

在添加邮件后,我有什么步骤需要考虑吗?发送<强>委派< /强>权限以使其生效?

这是我的密码:

    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;

    }
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();
        }
    }
}
static void Main(字符串[]args)
{
//Azure广告应用程序
字符串clientId=“”;
字符串tenantID=“”;
字符串clientSecret=“”;
Task callTask=Task.Run(()=>sendmail(clientId、tenantID、clientSecret));
//等它结束
callTask.Wait();
//得到结果
var asr=callTask;
}
公共静态异步任务SendEmail(字符串clientId、字符串tenantID、字符串clientSecret)
{
var secretentialclientapplication=secretentialclientapplicationbuilder
.Create(clientId)
.WithTenantId(tenantID)
.WithClientSecret(clientSecret)
.Build();
var authProvider=新的客户端凭据提供程序(机密客户端应用程序);
var graphClient=新的GraphServiceClient(authProvider);
var消息=新消息
{
主语,
Body=新项目Body
{
ContentType=BodyType.Text,
内容=内容
},
ToRecipients=新列表()
{
新收件人
{
EmailAddress=新EmailAddress{Address=收件人地址}
}
}
};
var saveToSentItems=true;
等待_graphClient.Users[]
.SendMail(消息,保存到存储项)
.Request()
.PostAsync();
返回图形客户端;
}
更新:

根据以下答案,我更新了代码如下:

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

            var authProvider = new UsernamePasswordProvider(publicClientApplication);

var publicClientApplication=PublicClientApplicationBuilder
.创建(“”)
.WithTenantId(“”)
.Build();
var authProvider=新用户名PasswordProvider(publicClientApplication);
var secureString=new NetworkCredential(“,”).SecurePassword;
User me=wait graphClient.me.Request()
.WithUsernamePassword(“,secureString)
.GetAsync();
我启用了“允许公共客户端流”来修复异常

现在我看到了另一个例外:权限不足,无法完成操作

我错过了什么

更新:目前我看到此异常,代码没有更改:

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

您提供的代码显示了用于进行身份验证的代码。使用
Mail.Send
应用程序权限时,使用客户端凭据流是可以的。但如果您使用
Mail.Send
委托权限,则我们无法使用客户端凭据。您应该使用来进行身份验证

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

下面是我的代码:

    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;

    }
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();
        }
    }
}
此代码用于获取用户(我)的信息,但不发送电子邮件,您尚未向应用程序添加权限。因此,它将显示
没有足够的权限来完成操作
。请删除此代码并改用“我的代码”中的代码块:

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


谢谢!我按照您的建议更新了代码,但我看到了一个例外。请看我更新的问题。您好@user989988请参考我答案中的“更新”。谢谢。我会试试你的代码。快速问题-是否可以使用委派权限发送邮件,而不在代码中提供用户密码?请告诉我。@user989988恐怕不行。如果你使用委托权限,你必须提供密码,无论你使用什么流(用户名/密码流,身份验证码流…)@user989988我在回答中的“Update2”下提供了我注册应用的两个屏幕截图,供你参考。