Email 尝试使用Microsoft Graph发送电子邮件时,Unauthorized/token不包含任何权限

Email 尝试使用Microsoft Graph发送电子邮件时,Unauthorized/token不包含任何权限,email,azure-active-directory,microsoft-graph-api,access-token,Email,Azure Active Directory,Microsoft Graph Api,Access Token,我们在Azure AD中注册了一个应用程序,并设置了客户端机密以将其作为守护程序应用程序运行(无需用户交互)。我们拥有Microsoft Graph API的API权限Mail.Send和User.Readadmin 我的理解是使用构造一个secretentialclientapplication来获取注册应用程序的访问令牌,通过它我可以创建一个GraphServiceClient。然后我可以使用客户端作为用户发送电子邮件 但我得到以下异常,表示令牌中没有权限:(但我确实提供了获取权限的范围)

我们在Azure AD中注册了一个应用程序,并设置了客户端机密以将其作为守护程序应用程序运行(无需用户交互)。我们拥有Microsoft Graph API的API权限
Mail.Send
User.Read
admin

我的理解是使用构造一个
secretentialclientapplication
来获取注册应用程序的访问令牌,通过它我可以创建一个GraphServiceClient。然后我可以使用客户端作为用户发送电子邮件

但我得到以下异常,表示令牌中没有权限:(但我确实提供了获取权限的范围)

相关代码:

// create a ConfidentialClientApplication:
var app = ConfidentialClientApplicationBuilder.Create(AppClientId)
                .WithAuthority(new Uri("https://login.microsoftonline.com/"+ TenantId + "/oauth2/v2.0/token"))
                .WithClientSecret(ClientSecretString)
                .Build();

            var scopes = new string[] { "https://graph.microsoft.com/.default" }; // if changed to "Mail.Send", it throws errors saying invalid scope.
            GraphServiceClient graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    async (requestMg) =>
                    {
                        // add access token to header
                        var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
                        requestMg.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
                    }));

  // send email:
try
            {
                var toAddress = "john_doe@helloworld.com";
                var SenderAddress = "jane_doe@helloworld.com";
                var recipient = new Recipient()
                {
                    EmailAddress = new EmailAddress()
                    {
                        Name = "John Doe",
                        Address = toAddress,
                    }
                };

                Message email = new Message
                {
                    Body = new ItemBody
                    {
                        Content = "<b>hello world</b>",
                        ContentType = BodyType.Html,
                    },
                    Subject = "hello world",
                    ToRecipients = new List<Recipient>() { recipient },
                };

                Console.WriteLine("hello 2");
                await graphClient.Users["john_doe@helloworld.com"].SendMail(email, false).Request().PostAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine("ex: " + ex);
            }
//创建机密客户端应用程序:
var app=secretentialClientApplicationBuilder.Create(AppClientId)
.WithAuthority(新Uri(“https://login.microsoftonline.com/“+TenantId+”/oauth2/v2.0/token”))
.WithClientSecret(ClientSecretString)
.Build();
变量范围=新字符串[]{”https://graph.microsoft.com/.default" }; // 如果更改为“Mail.Send”,则会抛出错误,表明作用域无效。
GraphServiceClient graphClient=新GraphServiceClient(
新的DelegateAuthenticationProvider(
异步(requestMg)=>
{
//将访问令牌添加到标头
var result=await app.AcquireTokenForClient(scopes.ExecuteAsync();
requestMg.Headers.Authorization=新的AuthenticationHeaderValue(“承载者”,result.AccessToken);
}));
//发送电子邮件:
尝试
{
var toAddress=“约翰_doe@helloworld.com";
var SenderAddress=“jane_doe@helloworld.com";
var recipient=新收件人()
{
EmailAddress=新的EmailAddress()
{
Name=“John Doe”,
地址,
}
};
消息电子邮件=新消息
{
Body=新项目Body
{
Content=“你好,世界”,
ContentType=BodyType.Html,
},
主题=“你好,世界”,
ToRecipients=new List(){recipients},
};
Console.WriteLine(“hello 2”);
等待graphClient.Users[“john_doe@helloworld.com“].SendMail(电子邮件,false).Request().PostAsync();
}
捕获(例外情况除外)
{
控制台写入线(“ex:+ex”);
}

那么,我如何请求将正确的权限放入访问令牌中?感谢您的帮助

因为您正在以应用程序的形式获取代币, 您很可能没有使用应用程序权限。 作为应用程序运行时不能使用委派权限, 因为这些仅适用于在用户上下文中运行的情况

您需要在Microsoft Graph API上添加Mail.Send应用程序权限, 然后管理员必须同意

// create a ConfidentialClientApplication:
var app = ConfidentialClientApplicationBuilder.Create(AppClientId)
                .WithAuthority(new Uri("https://login.microsoftonline.com/"+ TenantId + "/oauth2/v2.0/token"))
                .WithClientSecret(ClientSecretString)
                .Build();

            var scopes = new string[] { "https://graph.microsoft.com/.default" }; // if changed to "Mail.Send", it throws errors saying invalid scope.
            GraphServiceClient graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    async (requestMg) =>
                    {
                        // add access token to header
                        var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
                        requestMg.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
                    }));

  // send email:
try
            {
                var toAddress = "john_doe@helloworld.com";
                var SenderAddress = "jane_doe@helloworld.com";
                var recipient = new Recipient()
                {
                    EmailAddress = new EmailAddress()
                    {
                        Name = "John Doe",
                        Address = toAddress,
                    }
                };

                Message email = new Message
                {
                    Body = new ItemBody
                    {
                        Content = "<b>hello world</b>",
                        ContentType = BodyType.Html,
                    },
                    Subject = "hello world",
                    ToRecipients = new List<Recipient>() { recipient },
                };

                Console.WriteLine("hello 2");
                await graphClient.Users["john_doe@helloworld.com"].SendMail(email, false).Request().PostAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine("ex: " + ex);
            }