Недопустимый или просроченный токен контекста безопасности в веб-службе WCF - PullRequest
6 голосов
/ 27 мая 2009

All

У меня есть веб-служба WCF (давайте назовем ее службой "B"), размещенная в IIS с использованием учетной записи службы (ВМ, Windows 2003 SP2). Сервис предоставляет конечную точку, которая использует WSHttpBinding со значениями по умолчанию, за исключением maxReceivedMessageSize, maxBufferPoolSize, maxBufferSize и некоторых увеличенных тайм-аутов.

Веб-служба прошла нагрузочное тестирование с использованием платформы Visual Studio Load Test, в которой приняли участие около 800 одновременно работающих пользователей, и успешно прошла все тесты без исключений. Прокси в модульном тесте создан из конфигурации.

Существует приложение sharepoint, которое использует службу поиска Office Sharepoint Server для вызова веб-служб «A» и «B». Приложение получит данные из службы «А» для создания запроса, который будет отправлен в службу «Б». Ответ от службы "B" индексируется для поиска. Прокси создается программно с использованием ChannelFactory.

Когда услуга «А» занимает менее 10 минут, вызовы к услуге «Б» выполняются успешно. Но когда услуга «А» занимает больше времени (~ 20 минут), вызовы службы «Б» выдают следующее исключение:

Сообщение об исключении: незащищенная или неправильно защищенная ошибка была получена от другой стороны. См. Внутреннее исключение FaultException для получения кода ошибки и подробностей. Внутреннее сообщение об исключении: сообщение не может быть обработано. Это наиболее вероятно, потому что действие 'namespace / OperationName' является неправильным, или потому что сообщение содержит недопустимый или просроченный токен контекста безопасности или потому что существует несоответствие между привязками. Маркер контекста безопасности будет недействительным, если служба прервет канал из-за неактивности. Чтобы предотвратить прерывание незанятыми сеансами службы преждевременно, увеличьте время ожидания приема для привязки конечной точки службы.

Настройки привязки одинаковы, время на клиентском сервере и сервере веб-службы синхронизировано со службой времени Windows в одном часовом поясе.

Когда я смотрю на сервер, на котором размещен веб-сервис "B", я вижу следующие ошибки безопасности:

Источник: Безопасность

Категория: Вход / Выход из системы

Код события: 537

Пользователь NT AUTHORITY \ SYSTEM

Ошибка входа:

Причина: во время входа произошла ошибка

Тип входа: 3

Процесс входа в систему: Kerberos

Пакет аутентификации: Kerberos

Код статуса: 0xC000006D

Код подстатуса: 0xC0000133

После прочтения некоторых блогов в сети код статуса означает STATUS_LOGON_FAILURE, а код субстата - STATUS_TIME_DIFFERENCE_AT_DC. но я уже проверил часы сервера и клиента, и они синхронизированы.

Я также заметил, что токен безопасности, кажется, кэшируется где-то на клиентском сервере, потому что у них есть другой процесс, который вызывает веб-службу «B» с использованием той же учетной записи службы и успешно получает данные при первом вызове. Затем они запускают процесс обновления индексов службы поиска на сервере sharepoint, и он не работает. Тогда, если они снова вызвали первый процесс, он тоже потерпит неудачу.

Кто-нибудь сталкивался с подобными проблемами или есть идеи?

С уважением,

- Дамиан

Ответы [ 4 ]

5 голосов
/ 02 июля 2009

10 минут - время ожидания по умолчанию. Если у вас неактивный прокси-сервер в течение более 10 минут, сеанс безопасности этого прокси-сервера прерывается. Включите ведение журнала, и вы увидите это в журнале диагностики сервера. Сообщение об ошибке, о котором вы сообщили, подходит для такого поведения. Найдите в вашей системе диагностический файл "SessionIdleManager". Если вы найдете это, ваша проблема - выше.

Дайте ему развернуться и установите для InstallSecurityContext = "false" клиент и сервер.

3 голосов
/ 03 июня 2010

Не вызывайте операцию сервиса в операторе использования. Вместо этого используйте шаблон, такой как ...

client = new ServiceClient("Ws<binding>")
try
{
    client.Operation(x,y);
    client.Close();
}
catch ()
{
    client.Abort();
}

Я не понимаю, почему это работает, но я предполагаю, что когда прокси выходит из области видимости в операторе using, Close не вызывается. Затем служба ожидает истечения срока действия receiveTimeout (для привязки), а затем прерывает соединение, вызывая сбой последующих вызовов.

1 голос
/ 27 мая 2009

Я полагаю, что здесь происходит то, что ваш канал отключился (как вы подозреваете).

Если я правильно понимаю, это не звонки на обслуживание A , которые истекают, а скорее на обслуживание B , до вы вызываете свою операцию .

Я предполагаю, что вы создаете свой канал до , когда вы вызываете службу A , а не как раз вовремя (то есть до вызова службы B ). Вы должны создать канал (прокси, сервисный клиент) непосредственно перед его использованием, например:

AResponse aResp = null;
BResponse bResp = null;
using (ServiceAProxy proxyA = new ServiceAProxy())
{
   aResp = proxyA.DoServiceAWork();
   using (ServiceBProxy proxyB = new ServiceBProxy())
   {
      bResp = proxyB.DoOtherork(aResp);
   }
}
return bResp;

Я полагаю, однако, что как только вы преодолеете эту проблему (истечение времени ожидания службы B), вы поймете, что прокси-сервер приложения sharepoint (которое называется service A ) истечет время ожидания , Чтобы решить эту проблему, вы можете изменить модель обслуживания с запроса-ответа на модель публикации-подписки.

С помощью долго работающих сервисов вы захотите, чтобы ваше приложение sharepoint подписалось на сервис A, и чтобы сервис A опубликовал свои результаты, когда он будет готов сделать это, независимо от того, сколько времени это займет.

Программирование служб WCF (O'Reilly) Джувала Лоуи (Jval Lowey) дает отличное объяснение, и IDesign (компания Ювала) опубликовала отличный набор стандартов кодирования для WCF , а также код для отличного кода. Платформа публикации-подписки .

Надеюсь, это поможет, Ассаф.

0 голосов
/ 08 сентября 2010

Я на самом деле вызвал эту ошибку только сейчас, сделав что-то глупое. У меня есть модульный тест, который изменяет системную дату, чтобы проверить некоторые функции, основанные на времени. И я предполагаю, что очевидная разница во времени между тем, когда я создал контекст и когда я вызвал свой метод (из-за изменений в системной дате), привела к истечению срока действия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...