简体   繁体   English

使用外接程序中的Outlook Online令牌对用户进行身份验证以在线进行Exchange

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

Update 更新资料

It seems that the UserIdentityToken is not usable for identifying the user to Exchange Online. 似乎UserIdentityToken无法用于标识要在线交换的用户。 That token can be use by a third-party service (ie a custom chat account) for a reliable way to identify the current user. 第三方服务(即自定义聊天帐户)可以使用该令牌,以一种可靠的方式来标识当前用户。

We can rely on the callback token if we want to retrieve something from Exchange Online but there is a 5 minutes time limit . 如果要从Exchange Online检索内容,则可以依赖回调令牌 ,但是有5分钟的时间限制

If we absolutely want to avoid this limit, the only other way that I found is to ask for their Office 365 credentials. 如果我们绝对想避免此限制,那么我发现的唯一其他方法是询问他们的Office 365凭据。 Here is how I do it : 这是我的方法:

JS 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.NET MVC C#ASP.NET MVC

[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
}

Now you can do what you need with your mails. 现在,您可以处理您的邮件。


(Old post) (旧帖子)

I struggle with this. 我为此感到挣扎。 I would like to retrieve a bunch of emails with my ASP.NET MVC Web Server from Outlook online without the limit of the item token that have a lifetime of only 5 minutes. 我希望使用ASP.NET MVC Web Server从Outlook Online检索一堆电子邮件,而没有项目令牌的限制,该令牌的生命周期只有5分钟。

What I'm currently trying is : 我目前正在尝试的是:

Obviously, it doesn't work. 显然,它不起作用。 However, I tried to auth by entering the login and the password of my Office Account and here it does work. 但是,我尝试通过输入登录名和我的Office帐户的密码进行身份验证,在这里可以正常工作。

I read elsewhere that we have to validate our token before trying to authenticate with it but it seems to only concern external app with an Azure AD? 我在其他地方读过,在尝试对其进行身份验证之前,我们必须先验证我们的令牌,但它似乎仅涉及具有Azure AD的外部应用程序? In my case, that's just an Outlook Online WEB add-in . 就我而言,这只是一个Outlook Online WEB加载项

Well, here is my current code in my controller (that handle the authentication and that try to retrieve the mails from Exchange) 好吧,这是我当前在控制器中的代码(用于处理身份验证并尝试从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.context.mailbox.item.itemId参考

My goal is to avoid the user to enter their Office Online credentials again, it would be weird and... Insecure, I think. 我的目标是避免用户再次输入其Office Online凭据,这很奇怪,而且...不安全,我认为。 What I am missing, so? 我想念的是什么?

Thanks in advance. 提前致谢。

The ID token get from Office.context.mailbox.getUserIdentityTokenAsync() can only use to identify and authenticate the add-in and user with a third-party system . 从Office.context.mailbox.getUserIdentityTokenAsync()获得的ID令牌只能用于识别和验证第三方系统的加载项和用户

If you want to use the token get the item from Exchange through EWS, we need to use the token from getCallbackTokenAsync method. 如果要使用令牌通过EWS从Exchange获取项目,则需要使用getCallbackTokenAsync方法中的令牌。 And here is sample for your reference: 这是示例供您参考:

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);
    })
};

Web API: Web 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; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM