2009-05-26 1 views
6

Все,Неверный или истекли контекст безопасности маркер в веб-службы WCF

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

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

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

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

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

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

Когда я смотрю на сервере, где веб-сервис «B» размещенный я могу видеть ошибки следующей безопасности после входа:

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

Категория: Вход/выход

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

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

Отказ

входа:

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

Тип входа: 3

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

Пакет проверки подлинности: Kerberos

код Статус: 0xC000006D

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

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

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

У кого-нибудь возникли подобные проблемы или есть идеи?

С уважением,

--Damian

ответ

1

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

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

Я предполагаю, что вы создаете свой канал перед тем вы позвоните в службу , а не как раз вовремя (т.е. до вызова службы 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 (который называется услугой A) будет тайм-аут. Чтобы решить эту проблему, вы можете изменить свою модель обслуживания с помощью запроса-ответа на модель публикации-подписки.

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

Программирование WCF Services (O'Reilly) от Juval Lowey, имеет отличное объяснение, и IDesign (компания Juval) опубликовал a great set of coding standards for WCF, а также код для отличного Publish-Subscribe Framework.

Надеюсь, что это поможет, Assaf.

5

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

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

3

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

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

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

+0

Я прекратил работу с использованием статута для обслуживания. Если мне нужно его утилизировать, вызовите явную ((IDispose) Service) .Dispose(); наконец, –

+1

Проблема с оператором using заключается в том, что если во время вызова есть исключение, оператор using вызовет Dispose() на клиенте, который вызовет Close() на базовом канале. Поскольку соединение уже выполнено с ошибкой, это вызовет другое исключение, и, таким образом, первое исключение никогда не появится. – flayn

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^