На каком домене находится мой Javascript в моей надстройке Office - PullRequest
0 голосов
/ 28 февраля 2019

У нас есть надстройка Outlook, которая работает в OWA.

Когда я выполняю вызов из JavaScript в ответ на команду надстройки, я использую форматhttps://company.ourdomain.com/api/Controller/Action в вызове ajax.

В итоге я получаю одну из этих ошибок CORS (иногда это предполетная, а иногда CORB).Почему я получаю это, если Javascript буквально находится в том же домене, что и веб-сервис?

Я предполагаю, что я аутентифицирован, так как я вошел в свою учетную запись Outlook.

Что дает?

ПРИМЕЧАНИЕ. В качестве эксперимента я предпринял попытку вызова RESTful, введя URL-адрес напрямую (без OWA).Это вызвало проверку подлинности кода в Azure AD.Затем я вошел в OWA в том же сеансе браузера, и все работало нормально.Нужно ли мне на самом деле проходить аутентификацию в Javascript, даже если вызываемый мной веб-сервис находится в том же домене?

AJAX CALL, КОТОРЫЙ ГЕНЕРАРИРУЕТ ОШИБКУ Помните, что после того, как я это сделаю, все будет работать нормальноМы сделали вызов RESTful, позвонив в мой веб-сервис прямо из браузера

    var apiUri = '/api/People/ShowRecord';


$.ajax({
    url: apiUri,
    type: 'POST',
    data: JSON.stringify(serviceRequest),
    contentType: 'application/json; charset=utf-8',
    dataType: 'json'
}).done(function (response) {
    if (!response.isError) {
        // response to successful call
    }
    else {
        // ... 
    }
}).fail(function (status) {
    // some other response
}).always(function () {

    console.log("Completed");
});

НАБЛЮДЕНИЕ Когда я вызываю API из адресной строки, запускается приведенный ниже код.Этот код никогда не вызывается Javascript

[assembly: OwinStartup(typeof(EEWService.AuthStartup))]

namespace EEWService
{
    public partial class AuthStartup
    {
        public void Configuration(IAppBuilder app)
        { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {

                Notifications = new WsFederationAuthenticationNotifications
                {
                    RedirectToIdentityProvider = (context) =>
                    {
                        context.ProtocolMessage.Whr = "ourdomain.com";
                        return Task.FromResult(0);
                    }
                },

                MetadataAddress = ConfigurationManager.AppSettings["ida:MetadataAddress"],
                Wtrealm = ConfigurationManager.AppSettings["ida:Audience"],

                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudiences = new string[] { $"spn:{ConfigurationManager.AppSettings["ida:Audience"]}" }
                }
            });


        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
                },
                MetadataAddress = ConfigurationManager.AppSettings["ida:MetadataAddress"],
            });

    }
}

}

1 Ответ

0 голосов
/ 06 марта 2019

Есть несколько проблем с этим, я думаю.

Во-первых, вы пытаетесь обслуживать статический контент с того же сервера, с которого вы обслуживаете код.Это вообще считается плохой практикой, просто потому что нет смысла тратить эти драгоценные ресурсы сервера на статический контент.В идеале вы должны загрузить статический контент в CDN - и позволить браузеру пользователей сделать запрос на некоторый супер-кешированный файловый сервер.Однако - я понимаю, что эта опция может быть недоступна для вас на данный момент.Это также не является основной причиной.

Вторая и настоящая проблема в том, что (вы думаете, что это так, но) вы не аутентифицированы.Аутентификация в веб-надстройках Outlook не идет по умолчанию, это то, что вам нужно обработать.Когда Outlook загружает вашу веб-надстройку в боковую панель, она делает доступными определенные методы, которые вы можете использовать, и создаете псевдоидентификацию (например, Office.context.mailbox.userProfile.emailAddress) - но если выесли вам нужна настоящая аутентификация, вам нужно сделать это самостоятельно.

Насколько я могу судить, есть три способа сделать это.

  1. Первый - через Exchange Identity Token
  2. Второй - через функцию Single Sign On
  3. Третий - который, я думаю, наиболее удобен и прост в логикереализовать использует WebSockets.( SignalR может быть то, что вам нужно).
    • Когда пользователь загружает вашу первую страницу, убедитесь, что для него доступно значение JS, например window.Unique_ID.Это пригодится.
    • Есть кнопка в вашем пользовательском интерфейсе, которая гласит «Аутентификация»
    • Когда пользователь нажимает на эту кнопку, вы выдвигаете их на URL, который будет перенаправлять на вашURL аутентификации.(Что-то вроде https://company.ourdomain.com/redirToAuth). Это избавит вас от проблем с блокировкой на боковой панели, потому что вы используете window.open с URL-адресом, который находится в вашем домене. Передайте этот Unique_ID в перенаправление, которое затем перенаправит вас в OAuthURL для входа в систему. Это должно выглядеть следующим образом: https://login.microsoftonline.com/......&state=Unique_ID
    • Сразу после того, как пользователь введет окно входа в систему, в главном JS (на стороне клиента) вы откроете веб-сокет для своего сервера, снова сэтот Unique_ID и начать прослушивание.
    • Когда пользователь завершит аутентификацию, поток OAuth должен отправить обратно либо токен доступа, либо код. Если вы получите токен доступа, вы можете отправить его через сокеты на фронт-end (используя Unique_ID, который указан в параметрах post-back) или, если у вас есть код, вы завершаете аутентификацию пользователя с помощью межсерверного вызова и впоследствии передаете токен доступа таким же образом.Id для отслеживания сокета, к которому подключен пользователь, и передачи токена доступа только этому пользователю.
...