Microsoft.Graph - Отправить почту как пользователь сервиса - PullRequest
0 голосов
/ 17 октября 2018

В настоящее время я застрял в разработке моего Сервиса.Пользователи Сервиса используют интерфейсный 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...