Подписка EWS Streaming с Exchange Online

Мой главный вопрос: как при работе с Exchange Online должна работать потоковая подписка по отношению к периодическому обновлению токена доступа?

Подробности: я использую подписки на потоковую передачу EWS в течение некоторого времени для локального Exchange. Следуя обычному процессу, я создаю StreamingSubscriptionConnection, добавляю к нему подписки на почтовый ящик, а затем открываю соединение. Когда возникает событие OnDisconnect, мы повторно открываем соединение.

Мы реализовали подписку на потоковую передачу для почтовых ящиков в Exchange Online, которая требует от нас использования современной проверки подлинности с Microsoft.Identity.Client. Как указано в этом page, мы принудительно обновляем токен доступа каждые 30 минут в фоновом потоке.

Все отлично работает, пока мы не обновим токен доступа. В этот момент, когда срабатывает событие соединения OnDisconnect, и мы пытаемся повторно открыть соединение, происходит сбой 401 Unauthorized. В настоящее время у нас есть переназначение свойства Credentials объекта ExchangeService после обновления токена, но это, похоже, не оказывает никакого влияния на объекты StreamingSubscriptionConnection, которые были созданы до обновления токена.

Обратите внимание, что у класса StreamingSubscriptionConnection нет свойства Credentials, которое мы можем сбросить после обновления токена. Как объект подключения должен получать обновленные учетные данные?

Спасибо!

Джон

ОБНОВЛЕНИЕ

Оказывается, я не обновлял свойство Credentials объекта ExchangeService после обновления токена. Как только я разобрался с этим, повторное открытие соединения работает нормально.

Для всех, кому может быть интересно, вот как мы это делаем. Сначала определите объемы:

private string[] ewsScopes = new string[] { "https://outlook.office.com/.default" };

Теперь получите токен доступа:

_app = ConfidentialClientApplicationBuilder.Create(_EXOAppId)
        .WithAuthority(AzureCloudInstance.AzurePublic, _EXOTenantId)
        .WithClientSecret(_EXOClientSecret)
        .Build();

TokenCacheHelper.EnableSerialization(_app.AppTokenCache);

_EXOAuthResult = await _app.AcquireTokenForClient(ewsScopes).ExecuteAsync();

Затем установите таймер для периодического обновления токена (мы делаем это каждые 30 минут):

_nextRefresh = DateTime.Now.AddMinutes(refreshInterval);
_refreshTimer = new System.Timers.Timer();
_refreshTimer.Interval = 1000;
_refreshTimer.Elapsed += _refreshTimer_Elapsed;
_refreshTimer.Start();

И истекшее событие таймера:

private async void _refreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    if (DateTime.Now < _nextRefresh) return;

    _refreshTimer.Stop();

    _EXOAuthResult = await _app.AcquireTokenForClient(ewsScopes)
        .WithForceRefresh(true) // Do NOT force refresh every time!!
        .ExecuteAsync();

    //--> Here is where you would update the Credentials property of your ExchangeService

    _nextRefresh = DateTime.Now.AddMinutes(refreshInterval);
    _refreshTimer.Start();
}

Вот в основном это. Вам просто нужно убедиться, что вы правильно кешируете токен, что должно быть сделано с помощью TokenCacheHelper.


person Teeces    schedule 18.06.2020    source источник


Ответы (1)


Оказывается, я фактически не обновлял свойство Credentials объекта ExchangeService после обновления токена. Как только я разобрался с этим, повторное открытие соединения работает нормально.

person Teeces    schedule 19.06.2020