azure 使用ConfidentialClientApplicationBuilder时出现范围无效错误

nlejzf6q  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(134)

我正在使用ConfidentialClientApplicationBuilder获取令牌,然后发送电子邮件

var pca = ConfidentialClientApplicationBuilder
                     .Create(ClientId)
                     .WithClientSecret(clientSecret)
                     .WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
                     .WithRedirectUri(RedirectUrl)
                     .Build();



            var outlookScope = new string[] { "https://outlook.office365.com/SMTP.Send" };   // for graph use "https://graph.microsoft.com/.default"

            AuthenticationResult result = null;

            try
            {
                result = await pca.AcquireTokenForClient(outlookScope)
                    .ExecuteAsync();
            }
            catch (MsalException ex)
            {
                Console.WriteLine($"Error acquiring access token: {ex}");
            }

但我得到这个错误时,结果Microsoft.Identity.Client.MsalServiceException:'AADSTS 1002012:为作用域https://outlook.office365.com/SMTP.Send提供的值无效。客户端凭据流必须具有一个范围值,该范围值以/.default作为资源标识符(应用程序ID URI)的后缀。
我应该使用什么范围来成功获取token,然后我使用此smpt发送电子邮件

using (var emailClient = new MailKit.Net.Smtp.SmtpClient())
                {
                    var oauth2 = new SaslMechanismOAuth2(result.Account.Username, result.AccessToken);
                    await emailClient.ConnectAsync(SMPTServerName, SMPTServerPort, SecureSocketOptions.StartTls);  //google smtp.gmail.com
                    await emailClient.AuthenticateAsync(oauth2);

// Message Body 

await emailClient.SendAsync(message);

更新感谢Rukmini,我能够使用

var outlookScope = new string[] { "https://outlook.office365.com/.default" };

现在我遇到的问题是验证该令牌。这是密码

if (result != null)
                {
                    Console.WriteLine($"Access token: {result.AccessToken}");
    
                    var message = new MimeMessage();
                    message.From.Add(new MailboxAddress("Sender Name", "[email protected]"));
                    message.To.Add(new MailboxAddress("Recipient Name", "[email protected]"));
                    message.Subject = "Test Email";
                    message.Body = new TextPart("plain")
                    {
                        Text = "This is a test email sent using MailKit and Microsoft.Identity.Client."
                    };
    
                    using (var emailClient = new SmtpClient())
                    {
                        var oauth2 = new SaslMechanismOAuth2(result.Account.Username, result.AccessToken);
                        await emailClient.ConnectAsync("smtp.office365.com", 587, SecureSocketOptions.StartTls);
                        await emailClient.AuthenticateAsync(oauth2);
                        await emailClient.SendAsync(message);
                        await emailClient.DisconnectAsync(true);
                    }
                }

首先,结果Account为null,所以我得到这个错误x1c 0d1x
即使我把一个随机的用户名,得到这个错误MailKit.Security.AuthenticationException: '535: 5.7.3 Authentication unsuccessful [DX0P273CA0070.AREP273.PROD.OUTLOOK.COM 2023-10-16T04:50:43.626Z 08DBCDB69CE3A094]'

xj3cbfub

xj3cbfub1#

我在我的环境中尝试了相同的代码,得到了如下的相同的错误

注意:如果您使用客户端凭据流来生成访问令牌,则作用域必须将**/.default作为资源的后缀。在您的情况下,范围必须为https://outlook.office365.com/.default**
我修改了下面的代码,以获取Outlook资源的访问令牌:

using Microsoft.Identity.Client;
using System;

namespace ConsoleApp1
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            string ClientId = "ClientID";
            string clientSecret = "ClientSecret";
            string Tenant = "TenantID";
            string RedirectUrl = "https://jwt.ms";

            var pca = ConfidentialClientApplicationBuilder
                .Create(ClientId)
                .WithClientSecret(clientSecret)
                .WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
                .WithRedirectUri(RedirectUrl)
                .Build();

            var outlookScope = new string[] { "https://outlook.office365.com/.default" };

            AuthenticationResult result = null;

            try
            {
                result = await pca.AcquireTokenForClient(outlookScope)
                    .ExecuteAsync();
            }
            catch (MsalException ex)
            {
                Console.WriteLine($"Error acquiring access token: {ex}");
            }

            if (result != null)
            {
                Console.WriteLine($"Access token: {result.AccessToken}");
            }
        }
    }
}

解码令牌:

更新:

您可以使用Microsoft Graph API发送邮件,如下所示:
授予API权限:

使用下面的代码:

using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Graph.Models.ODataErrors;

var scopes = new[] { "https://graph.microsoft.com/.default" };

var clientId = "XXX";
var tenantId = "XXX";
var clientSecret = "***";

var options = new ClientSecretCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};

var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);

var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

var requestBody = new Microsoft.Graph.Users.Item.SendMail.SendMailPostRequestBody
{
    Message = new Message
    {
        Subject = "Test mail",
        Body = new ItemBody
        {
            ContentType = BodyType.Html,
            Content = "This is Test mail",
        },
        ToRecipients = new List<Recipient>
        {
            new Recipient
            {
                EmailAddress = new EmailAddress
                {
                    Address = "user@***.onmicrosoft.com",
                },
            },
        },
    },
};
try
{
    await graphClient.Users["user1@**.onmicrosoft.com"].SendMail.PostAsync(requestBody);
    Console.WriteLine("Successfully sent mail");
}
catch (ODataError odataError)
{
    Console.WriteLine(odataError.Error.Code);
    Console.WriteLine(odataError.Error.Message);
}

相关问题