Microsoft.Graph-以服务用户身份发送邮件

时间:2018-10-17 08:51:12

标签: c# web-services email

我目前只能开发我的服务。服务的用户使用前端胖客户端并连接到我的Rest Service。它们将通过NTLM进行认证。

由于我的服务呼叫其他服务,因此该服务会模拟每个外部呼叫。

在某个时候,服务会发送一封电子邮件。在我的公司中,我们使用Active Directory。该服务在具有访问权的用户和邮箱下运行。服务不应提示登录或类似的内容。

现在,我正尝试通过Microsoft.Graph API发送邮件。但是我找不到任何发送邮件的方法。我总是遇到一些错误。

我得到的最后一个错误是:

  

当前已认证的上下文对此请求无效。当对需要用户登录的端点发出请求时,就会发生这种情况。例如,/ me需要登录的用户。代表用户获取令牌以向这些端点发出请求。将OAuth 2.0授权代码流用于移动和本机应用程序,并将OAuth 2.0隐式流用于单页Web应用程序。

这似乎“确定”。因为我仍然是假冒的。但是,如何恢复模拟?或者如何代表我发送邮件?

在我的设置下面:

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。那不重要。

//编辑

我现在终于解决了。我现在使用以下Windows身份验证

private static async Task<string> GetAccessTokenAsync()
{
    var authContext = new PublicClientApplication(ClientId, Authority, TokenCache);
    var authResult = await authContext.AcquireTokenByIntegratedWindowsAuthAsync(ApplicationScopes);
    return authResult.AccessToken;
}

0 个答案:

没有答案