到目前为止,我们使用基本身份验证从我们的服务器使用 Microsoft Office365 发送电子邮件。现在他们关闭了基本身份验证,只有 OAuth 正在工作。
我在互联网上查看了如何将 OAuth 添加到我们的服务器,并找到了以下方面:https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-credential-flows
我的代码如下所示,我获得了访问令牌。
private readonly string[] _scopes =
{
$"{_emailOption.myUri}/.default"
};
public async Task ActivateOAuth()
{
_emailoptions.ConfidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(_emailoptions.ClientId)
.WithClientSecret(_emailoptions.ClientSecret)
.Build();
var authenticationResult = await _emailoptions.ConfidentialClientApplication
.AcquireTokenForClient(_scopes)
.WithAuthority(AzureCloudInstance.AzurePublic, _emailoptions.TenantId)
.ExecuteAsync();
await SendSuccessfulAuthenticatedEmail(_email.FromAddress, authenticationResult.AccessToken);
}
现在要发送电子邮件,我正在使用 MailKit 库,它能够使用 OAuth 身份验证。但是当我尝试
client.AuthenticatAsync(oAuth2)
时,代码总是崩溃并出现错误: AuthenticationInvalidCredentials: 5.7.3 Authentication unsuccessful
private async Task SendSuccessfulAuthenticatedEmail(string username, string accessToken)
{
var oAuth2 = new SaslMechanismOAuth2(username, accessToken);
using var client = new SmtpClient();
await client.ConnectAsync(_emailoptions.SmtpHost, _emailoptions.SmtpPort, _emailoptions.SmtpSecureOptions);
await client.AuthenticateAsync(oAuth2); // Here the Code Crashes
var message = new MimeMessage();
message.From.Add(new MailboxAddress(_emailoptions.FromUserName, _emailoptions.FromAddress));
message.To.Add(new MailboxAddress(_emailoptions.FromAddress, _emailoptions.FromAddress));
var bodyBuilder = new BodyBuilder();
bodyBuilder.TextBody = $"This is the Information, that the OAuth2 is now Activated on ***** Server.{_emailoptions.ServerBase}";
message.Body = bodyBuilder.ToMessageBody();
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
所以我有一个来自我公司应用程序的access_token,但它不能与特定用户一起发送电子邮件。但我在设置中允许发送电子邮件:
那么,为什么使用这些设置无法从公司帐户发送电子邮件?是的,SMTP 身份验证已启用。
添加
如果我使用以下方法的代码
_emailoptions.ConfidentialClientApplication.GetAuthorizationRequestUrl(_scopes)
,然后将Url复制到浏览器并使用帐户登录,然后获取令牌_emailoptions.ConfidentialClientApplication.AcquireTokenByAuthorizationCode()
,那么我就可以正常工作了。但我不想每次服务器重启后都登录。
一旦您的应用程序被注册,租户管理员将需要注册您的服务主体。
要使用 New-ServicePrincipal cmdlet,请安装 ExchangeOnlineManagement 并连接到您的租户,如以下代码段所示:
Install-Module -Name ExchangeOnlineManagement -allowprerelease
Import-module ExchangeOnlineManagement
Connect-ExchangeOnline -Organization <tenantId>
接下来,为您的应用程序注册服务主体:
New-ServicePrincipal -AppId <APPLICATION_ID> -ObjectId <OBJECT_ID> [-Organization <ORGANIZATION_ID>]
现在您需要授予应用程序访问电子邮件帐户的权限。
为此,您需要首先使用以下命令获取在上一步中注册的服务主体 ID:
Get-ServicePrincipal | fl
获得应用程序的服务主体 ID 后,请使用以下命令为应用程序将访问的电子邮件帐户添加完整邮箱权限:
Add-MailboxPermission -Identity "[email protected]" -User
<SERVICE_PRINCIPAL_ID> -AccessRights FullAccess