"Недействительный или устаревший токен безопасности" при запуске после перезапуска

У меня есть приложение WCF, которое я кодирую. Я запускаю и останавливаю его несколько раз, когда я меняю вещи, а затем снова запускаю служебный вызов.

Поскольку мне нужна информация о сеансе, я использую wsHttpBinding.

Прежде чем перейти к wsHttpBinding, я использовал basicHttpBinding, и я мог остановить службу, внести изменения и перезапустить ее. Затем я смог запустить мой тестовый клиент WCF (WCF Storm) против конечной точки, и он все равно будет работать нормально.

Теперь он говорит мне:

Сообщение не может быть обработано. Это наиболее вероятно, потому что действие http://tempuri.org/IMyService/MyOperation 'неверно или потому, что сообщение содержит недопустимый или истекший токен безопасности или из-за несоответствия между привязками. Токен контекста безопасности был бы недействительным, если служба прервала канал из-за неактивности. Чтобы предотвратить прерывание сеансов бездействия, служба преждевременно увеличивает тайм-аут приема на привязку конечной точки службы.

Это означает, что мне нужно обновить мое соединение и повторно настроить мой служебный вызов (который вызывает раздражение после нескольких сотен раз.).

Я прочитал, что тайм-аут безопасности составляет 10 минут. Я забегаю менее чем за 2 минуты, поэтому я не думаю, что это проблема с тайм-аутом.

Я предполагаю, что токен истекает по той очевидной причине, что я убил и перезапустил службу.

Дело в том, что мне вообще не нужен материал безопасности (мне нужен только материал сеанса, или я бы использовал BasicHttpBinding

В любом случае, чтобы моя служба WCF не заботилась о токенах контекста безопасности?

Примечание. Мой тестовый клиент по умолчанию использует wsHttpBinding и имеет набор безопасности. Но я предполагаю, что он устанавливает это, потому что мой сервис публикует, что ему нужна безопасность.

Вещи, которые я пробовал:

  • Я пробовал конфигурацию, подобную той, что я нашел здесь

    <bindings>
        <wsHttpBinding>
            <binding name="WsEventLogBinding">
                <security mode="Message">
                    <message establishSecurityContext="false" />
                </security>
             </binding>
        </wsHttpBinding>
    </bindings>
    

Но я действительно не знаю, что это значит, или если это то, что мне нужно (что вообще не является безопасностью (пока)).

Это не устранило проблему.

  • Настройка <security mode="None"> Это не помогло.

Ответ 1

Сначала вы прав: basicHttpBinding не поддерживает это из-за отсутствия/отсутствия доступа к HTTP-протоколу без установления соединения.

Но я думаю, что в вашем понимании WCF что-то не так.

Сессия является общим понятием в WCF. Это может быть сеанс на основе безопасности, в котором оба конца связи согласовали конкретную безопасную беседу или реальный сеанс, в котором сообщения могут быть настроены для доставки по порядку и ровно один раз, обеспечивая получение сообщений, даже когда сообщения перемещаются по нескольким узлов во время разговора.

Оба режима позволяют вам выбирать InstanceContextMode.PerSession. Это действительно то, что вам нужно?

Безопасность WCF зависит от взаимной аутентификации; Если обе стороны доверяют другим учетным данным (на основе требований), тогда может быть установлен безопасный контекст, в котором все сообщения обмениваются в конфиденциальности, а все сообщения подписываются для защиты их целостности. Сеанс безопасности уникален, и вы не можете его повторно использовать в другом разговоре.

Вот проблема с вашим контекстом: проблема не в стороне сервера, а на стороне клиента. Поскольку что-то должно храниться на клиенте и на сервисе, восстановление службы очистит весь контекст WCF в службе (все экземпляры и сеансы будут удалены). Нет общего хранилища данных, связанного с сеансами WCF (одно отличие от asp.NET session), поэтому перезапуск все-таки упадет. Тем не менее, клиент по-прежнему считает, что он аутентифицирован из-за своего "недействительного" контекста.

Чтобы решить эту проблему, установлен флажок для этого сценария для тестового клиента Wcf по умолчанию: "Начать новый прокси". В WCf Storm есть общая конфигурация в разделе "Капот/Разное" всегда создавайте новый прокси.

Примечание. При производстве у вас никогда не будет такого сценария, потому что ваш сервис всегда будет работать.

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

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>

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

Ответ 2

wsHttpBinding имеет защиту по умолчанию. Попробуйте использовать эту настройку привязки для отключения безопасности:

<security mode="None">
   <transport clientCredentialType="None" />
    <message establishSecurityContext="false" />
</security>

Кроме того, ваша ошибка связана с wsHttpBinding. Если вы используете сеансы и перезагружаете сервер, появится сообщение об ошибке безопасности .

Согласно MSDN:

Надежная сессия реализует протокол WS-ReliableMessaging и в окне переноса памяти для маскировки ошибок на уровне сообщений SOAP и восстанавливает соединения в случае транспортных сбоев.

и

Надежный сеанс между отправителем и получателем SOAP конечных точек, независимо от количества требуемых транспортных соединений для связи между ними. Короче говоря, надежность TCP заканчивается там, где транспортное соединение заканчивается, тогда как надежный сеанс обеспечивает сквозная надежность.

Звучит как ожидаемое поведение.

Ответ 4

Режим защиты Нет должно выполнять задание.

<bindings>
    <wsHttpBinding>
        <binding name="WsEventLogBinding">
            <security mode="None" />
         </binding>
    </wsHttpBinding>
</bindings>

Не забудьте применить bindingConfiguration="WsEventLogBinding" к вашей конечной точке.