В настоящее время я застрял в разработке моего Сервиса.Пользователи Сервиса используют интерфейсный Fat-клиент и подключаются к моей Службе отдыха.Они будут аутентифицированы через NTLM.
Поскольку моя Служба вызывает другие службы, Служба олицетворяет каждый внешний вызов.
В какой-то момент Служба отправляет электронное письмо.В моей компании мы используем Active Directory.Сервис работает под пользователем, который имеет к нему доступ, а также с почтовым ящиком.Служба не должна запрашивать вход в систему или что-то в этом роде.
Теперь я пытаюсь отправить Почту через Microsoft.Graph API.Но я не нахожу способа отправить письмо.Я всегда получаю некоторые ошибки.
последняя ошибка, которую я получил, следующая:
Текущий контекст аутентификации недопустим для этого запроса.Это происходит, когда запрос сделан к конечной точке, которая требует входа пользователя.Например, для / me требуется зарегистрированный пользователь.Получите токен от имени пользователя для отправки запросов к этим конечным точкам.Используйте поток кода авторизации OAuth 2.0 для мобильных и собственных приложений и неявный поток OAuth 2.0 для одностраничных веб-приложений.
Кажется, что все в порядке.Потому что я до сих пор бегаю за себя.Но как я могу отменить олицетворение?Или как я могу отправить Почту от имени?
Ниже моей настройки:
private const string Authority = "https://login.microsoftonline.com/common";
internal const string ClientId = "MyClientID";
internal const string AppSecret = "MyAppSecret";
private static readonly TokenCache TokenCache = new TokenCache();
public void SendMail(string recipients, string subject, string body, string attachments, bool sendAsHtml)
{
this._log.Information($"Trying to send Mail with Subject {subject} to {recipients}...");
var mailRecipients = this.GetRecipients(recipients);
var mailAttachments = this.GetAttachments(attachments);
var mail = this.CreateMail(mailRecipients, subject, body, mailAttachments, sendAsHtml);
var graphClient = this.GetAuthenticatedClient();
// Tried to send "OnBehalf" but didn't work:
//var mailRequestBuilder = graphClient.Users["ServiceUserName"].SendMail(mail, true);
var mailRequestBuilder = graphClient.Me.SendMail(mail, true);
var sendMailRequest = mailRequestBuilder.Request();
sendMailRequest.PostAsync().GetAwaiter().GetResult();
this._log.Information($"Successful send Mail with Subject {subject} to {recipients}.");
}
private Message CreateMail(IEnumerable<Recipient> mailRecipients, string subject, string body, IMessageAttachmentsCollectionPage mailAttachments, bool sendAsHtml)
{
return new Message
{
ToRecipients = mailRecipients,
Subject = subject,
Body = new ItemBody
{
Content = body,
ContentType = sendAsHtml ? BodyType.Html : BodyType.Text
},
Attachments = mailAttachments
};
}
private IMessageAttachmentsCollectionPage GetAttachments(string attachments)
{
var list = new MessageAttachmentsCollectionPage();
var attachmentList = attachments?.Split(';');
if (attachmentList.IsNullOrEmpty())
return list;
foreach (var attachment in attachmentList)
{
if (File.Exists(attachment))
list.Add(this.CreateAttachment(attachment));
}
return list;
}
private FileAttachment CreateAttachment(string attachmentPath)
{
return new FileAttachment
{
ODataType = "#microsoft.graph.fileAttachment",
ContentBytes = File.ReadAllBytes(attachmentPath),
Name = Path.GetFileName(attachmentPath),
};
}
private IReadOnlyCollection<Recipient> GetRecipients(string recipients)
{
if (string.IsNullOrWhiteSpace(recipients))
throw new ArgumentNullException(nameof(recipients), "No recipient specified.");
var recipientList = (from rec in recipients.Split(';')
let recipient = rec.Trim()
where !string.IsNullOrEmpty(recipient)
select CreateRecipient(recipient)).ToArray();
if (recipientList.Length == 0)
throw new ArgumentNullException(nameof(recipients), "No recipient specified.");
return recipientList;
}
private static Recipient CreateRecipient(string recipient)
{
return new Recipient
{
EmailAddress = new EmailAddress
{
Address = recipient
}
};
}
private GraphServiceClient GetAuthenticatedClient()
{
var graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(AuthenticateGraphClientAsync));
return graphClient;
}
private static Task AuthenticateGraphClientAsync(HttpRequestMessage request)
{
return Task.Run(() =>
{
var accessToken = GetAccessToken();
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
});
}
private static string GetAccessToken()
{
var authContext = new AuthenticationContext("https://login.windows.net/common/", TokenCache);
var credentials = new ClientCredential(ClientId, AppSecret);
var authResult = authContext.AcquireTokenAsync("https://graph.microsoft.com/", credentials).GetAwaiter().GetResult();
return authResult.AccessToken;
}
Кто-нибудь знает, как моя Служба может отправлять электронную почту?Это может быть как Пользователь службы, как Пользователь, который запрашивает его, так и OnBehalf.Это не важно.
// Edit
Теперь я наконец исправил это.Я использовал аутентификацию Windows следующим образом
private static async Task<string> GetAccessTokenAsync()
{
var authContext = new PublicClientApplication(ClientId, Authority, TokenCache);
var authResult = await authContext.AcquireTokenByIntegratedWindowsAuthAsync(ApplicationScopes);
return authResult.AccessToken;
}