Внедрение API календаря Outlook в надстройке Outlook

Я пытаюсь реализовать Office365 Outlook Calendar API внутри надстройки Outlook 365. API календаря Outlook полностью реализован в веб-приложении. Все отлично работает с OAuth2 и возвращенным auth_token в веб-приложении.

У меня проблемы со входом с помощью OAuth2 внутри надстройки. Если вы откроете OAuth2-Login от Microsoft внутри надстройки, он откроет экземпляр Internet Explorer после того, как вы войдете в свою com-учетную запись appdev **** @ outlook [точка]. Это не работает с auth_token, сохраненным в сеансе.

Я попытался сохранить auth_token в базе данных (см. // Тестовая часть) и запросить его для пользователя внутри надстройки. Это ошибка с DataServiceClientException: Unauthorized Unknown location.

    [Route("SignIn")]
    public async Task<ActionResult> SignIn()
    {
        string authority = "https://login.microsoftonline.com/common";

        string clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
        AuthenticationContext authContext = new AuthenticationContext(authority);

        Uri redirectUri = new Uri(Url.Action("Authorize", "outlook", null, HttpContext.Request.Scheme));

        Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(scopes, null, clientId,
            redirectUri, UserIdentifier.AnyUser, null);

        return Redirect(authUri.ToString());
    }

    [Route("Authorize")]
    public async Task<ActionResult> Authorize()
    {
        string authCode = Request.Query["code"];

        string authority = "https://login.microsoftonline.com/common";

        string clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
        string clientSecret = "xxxxxxxxxxxx";
        AuthenticationContext authContext = new AuthenticationContext(authority);

        Uri redirectUri = new Uri(Url.Action("Authorize", "outlook", null, HttpContext.Request.Scheme));

        ClientCredential credential = new ClientCredential(clientId, clientSecret);

        try
        {
            var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                authCode, redirectUri, credential, scopes);

            HttpContext.Session.SetString("access_token", authResult.Token);
            HttpContext.Session.SetString("user_email", GetUserEmail(authContext, clientId));

            //*** TEST ***
            _dbContext.ApplicationUsers.FirstOrDefault(e => e.Email == "appdev****@outlook.com").AccessToken = authResult.Token;
            _dbContext.ApplicationUsers.FirstOrDefault(e => e.Email == "appdev****@outlook.com").Email = GetUserEmail(authContext, clientId);

            return Content("Access Token: " + authResult.Token + " Email: " + GetUserEmail(authContext, clientId));
        }
        catch (AdalException ex)
        {
            return Content(string.Format("ERROR retrieving token: {0}", ex.Message));
        }
    }

person Konstantin Kreft    schedule 11.01.2016    source источник


Ответы (1)


Новый ответ. Это распространенная проблема с надстройкой Office нового поколения (бывшее приложение для Office) и аутентификацией OAUTH. Тот факт, что надстройка запускается в изолированном iFrame, заставляет аутентификацию выполняться во всплывающем окне. Также есть некоторые проблемы с получением токена аутентификации в родительском (изолированном iFrame) окне, потому что обмен фреймами в этом контексте запрещен. Я предложил решение здесь, но лучшее решение исходит от Ричарда ДиЗереги и предлагается здесь. Насколько я понял, вы пытаетесь сохранить auth_token в базе данных, чтобы он позже был запрошен надстройкой iFrame. Это закрыто для того, что предлагает Ричард ДиЗерега.

Старый ошибочный ответ. Вы столкнулись с этой проблемой, потому что, вероятно, зарегистрировали приложение Azure AD как веб-приложение. Теперь вы запрашиваете его с помощью собственного клиента без какого-либо «URL-адреса», поэтому это не удается.

Существует другой сценарий аутентификации для собственный клиент.

Думаю, в этом нет ничего страшного, просто зарегистрируйте другое приложение в Azure AD для собственного клиента (это первый вопрос, который задают при создании приложения).

person Benoit Patra    schedule 12.01.2016
comment
Я не размещаю на лазурном сервере ни веб-приложение, ни надстройку. Я зарегистрировал надстройку через: apps.dev.microsoft.com. Далее я использую angular во внешнем интерфейсе, чтобы использовать преимущества одностраничного приложения. Недавно я прочитал об OpenID Connect для получения ключа авторизации вместо OAuth2. Подходит ли OpenID Connect для моего проекта? - person Konstantin Kreft; 12.01.2016
comment
1. Регистрация приложения в azureAD отличается от «размещения» приложения или надстройки в Azure. Это только для целей аутентификации и запроса Microsoft API (Office365 / Graph API и т. Д.), Веб-приложение может быть размещено в любом другом месте, а также может быть собственным клиентским приложением. Я не знал о apps.dev.microsoft.com, но он не кажется таким мощным, как AzureAD. - person Benoit Patra; 13.01.2016
comment
2- Я использую соединение OpenID для потока авторизации кода, когда сервер выполняет аутентифицированный запрос к API Office365 вместо самого клиента (собственный клиент или веб-приложение SPA). Это намного сложнее, но в моем случае это было необходимо. Если вам нужен только клиент (а не сервер) для выполнения запросов к API Outlook, я предлагаю вам взглянуть на adal.js или adal angular. Здесь много примеров github.com/AzureAD - person Benoit Patra; 13.01.2016
comment
Прочитав еще раз ваш вопрос и вижу, что совершенно ошибался. Когда вы говорили о надстройке, я подумал о надстройке клиента .NET. - person Benoit Patra; 13.01.2016
comment
Ох, хорошо. Это надстройка Outlook 365 / Exchange. Только XML-файл и мое размещенное веб-приложение. Для получения дополнительной информации: веб-приложение запускает ASP.Net 5, MVC 6 и AngularJS. - person Konstantin Kreft; 13.01.2016