Мой главный вопрос: как при работе с Exchange Online должна работать подписка на потоковое вещание в отношении периода c refre токена доступа sh?
Подробности. Я использую подписки на потоковую передачу EWS в течение некоторого времени для локального Exchange. Следуя обычному процессу, я создаю StreamingSubscriptionConnection
, добавляю к нему подписки на почтовый ящик, а затем открываю соединение. Когда возникает событие OnDisconnect
, мы повторно открываем соединение.
Теперь мы реализовали подписку на потоковую передачу для почтовых ящиков в Exchange Online, которая требует от нас использования современной аутентификации с Microsoft.Identity.Client. Как указано на этой странице , мы принудительно обновляем sh токена доступа каждые 30 минут в фоновом потоке.
Все работает отлично, пока мы не обновим sh доступ токен. В этот момент, когда срабатывает событие подключения OnDisconnect
, и мы пытаемся повторно открыть соединение, происходит сбой 401 Unauthorized. В настоящее время у нас есть переназначение свойства Credentials
объекта ExchangeService
после обновления токена, но это, похоже, не оказывает никакого влияния на объекты StreamingSubscriptionConnection
, которые были созданы до обновления токена.
Обратите внимание, что у класса StreamingSubscriptionConnection
нет свойства Credentials
, которое мы можем сбросить после обновления токена sh. Как объект подключения должен получить обновленные учетные данные?
Спасибо!
John
UPDATE
Оказывается Фактически я не обновлял свойство 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();
Затем установите таймер, чтобы периодически обновлять sh токен (мы делаем это каждые 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.