使用加载项中的 Outlook Online 令牌对用户进行在线 Exchange 身份验证

Authenticate user to Exchange online with Outlook online token from an add-in

更新

UserIdentityToken 似乎无法用于识别 Exchange Online 的用户。第三方服务(即自定义聊天帐户)可以使用该令牌作为识别当前用户的可靠方式。

如果我们想从 Exchange Online 检索某些内容,我们可以依赖 回调令牌,但有 5 分钟的时间限制

如果我们绝对想避免此限制,我发现的唯一其他方法是询问他们的 Office 365 凭据。这是我的做法:

JS

// Send Basket Button | Send the basket to Sharepoint
$("#sendMails").click(function () {
    var mailsId = getMailIds();
    if (mailsId != null) saveMails(mailsId);
});

function saveMails(mailsId) {
    $.post(
        "/AJAX/SaveMails"
        {
            mailsId: JSON.stringify(mailsId),
            login: "mymail@onmicrosoft.com",
            password: "mypass",
        },
        function(result) {
            console.log("saveMails : ", result);
        },
        "text"
    );
}

C#ASP.NETMVC

[HttpPost]
public ActionResult SaveMails()
{
    // Office365 credentials
    var login = Request["login"];
    var password = Request["password"];

    // mailsID to retrieve from Exchange
    // IDs come from Office.context.mailbox.item.itemId
    var mailsID = JsonConvert.DeserializeObject<List<string>>(Request["mailsID"]);

    // Set credentials and EWS url for the Exchange connection
    var exService = new ExchangeService
    {
        // User's credentials
        Credentials = new WebCredentials(login, password),

        // Exchange Uri (always the same for Office365)
        Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx")
    }

    foreach(var mail in mailsID)
    {
         var itemId = new ItemId(mail);
         // Get mails from Exchange Online
         var email = EmailMessage.Bind(exService, itemId);

         // ... Do something with the mail
    }

    // ... Rest of the code
}

现在您可以对邮件进行所需的操作。


(旧post)

我为此苦苦挣扎。我想使用我的 ASP.NET MVC Web 服务器 从 Outlook 在线检索一堆电子邮件,而没有生命周期只有 5 分钟的项目令牌的限制。

我目前正在尝试的是:

显然,它不起作用。但是,我尝试通过输入我的 Office 帐户的 登录名和密码 来进行身份验证,在这里它确实有效。

我在别处读到我们必须先验证我们的令牌,然后再尝试对其进行身份验证,但它似乎只涉及带有 Azure AD 的外部应用程序?就我而言,这只是 一个 Outlook Online WEB 加载项

嗯,这是我控制器中的当前代码(处理身份验证并尝试从 Exchange 检索邮件)

[HttpPost]
public ActionResult GetMails()
{
    // Token from getUserIdentityTokenAsync() as a string
    var token = Request["token"];

    // mailsID to retrieve from Exchange
    // IDs come from Office.context.mailbox.item.itemId
    var mailsID = JsonConvert.DeserializeObject<List<string>>(Request["mailsID"]);


    var exService = new ExchangeService
    {
        Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
        Credentials = new OAuthCredentials(token),

        // WebCredentials works but I don't want the user to enter that
        // Credentials = new WebCredentials("mymail@onmicrosoft.com", "mypass");
    }

    foreach(var mail in mailsID)
    {
         var itemId = new ItemId(mail);
         // Try to get the mail from Exchange Online
         var email = EmailMessage.Bind(exService, itemId);

         // ... Rest of the code
    }

    // ... Rest of the method
}

Office.context.mailbox.item.itemId reference

我的目标是避免用户再次输入他们的 Office Online 凭据,这会很奇怪而且...不安全,我认为。我缺少什么,所以?

提前致谢。

从Office.context.mailbox.getUserIdentityTokenAsync()获取的ID token只能用于识别和authenticate the add-in and user with a third-party system

如果要使用令牌通过 EWS 从 Exchange 获取项目,我们需要使用来自 getCallbackTokenAsync 方法的令牌。这是供您参考的示例:

function getMails2() {
    Office.context.mailbox.getCallbackTokenAsync(function (rs) {
        callMyWebService(rs.value, Office.context.mailbox.item.itemId)
    })
}

function callMyWebService(token, itemID) {
    var customer = { "token": token, "id": itemID };
    $.ajax({
        url: '../../api/Default',
        type: 'POST',
        data: JSON.stringify(customer),
        contentType: 'application/json;charset=utf-8'
    }).done(function (response) {
        if (!response.isError) {
            var names = "<h2>Attachments processed using " +
                          serviceRequest.service +
                          ": " +
                          response.attachmentsProcessed +
                          "</h2>";
            for (i = 0; i < response.attachmentNames.length; i++) {
                names += response.attachmentNames[i] + "<br />";
            }
            document.getElementById("names").innerHTML = names;
        } else {
            app.showNotification("Runtime error", response.message);
        }
    }).fail(function (status) {

    }).always(function () {
        $('.disable-while-sending').prop('disabled', false);
    })
};

网络API:

// POST api/<controller>
    public void Post([FromBody]Customer customer)
    {
        var token = customer.Token;

        // mailsID to retrieve from Exchange
        // IDs come from Office.context.mailbox.item.itemId
        // var mailsID = JsonConvert.DeserializeObject<List<string>>(customer.Id);



        var exService = new ExchangeService
        {
            Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
            Credentials = new OAuthCredentials(token),

            // WebCredentials works but I don't want the user to enter that
            // Credentials = new WebCredentials("mymail@onmicrosoft.com", "mypass");
        };

        var itemId = new ItemId(customer.Id);
        // Try to get the mail from Exchange Online
        var email = EmailMessage.Bind(exService, itemId);
        string subject = email.Subject; 
        // ... Rest of the code

    }

public class Customer
{
    public string Token { get; set; }
    public string Id { get; set; }
}