Ответ 1
Хорошо, после нескольких попыток я понял это. Отправляя это, если другие сталкиваются с той же проблемой.
Я должен продолжить, отметив, что это поведение действительно нужно упомянуть где-то в MSDN, в месте, которое действительно доступно для всех, кто ищет информацию о безопасности WCF и не зарывается глубоко в какую-либо документацию по инструментарию.
Платформы, на которых я смог воспроизвести и исправить это: Windows 8.1 x64 и Windows Server 2008 R2 Standard.
Как я уже упоминал, моя проблема заключалась в том, что я не смог настроить безопасность WCF, чтобы для службы требовались клиентские сертификаты. Общая путаница, которую я заметил при поиске решения, заключается в том, что многие люди считают, что клиент может отправить сертификат, если он есть, без ответа. Это, конечно, не тот случай - сервер должен сначала запросить его, и, кроме того, указать, какие CAs разрешены через ответ CertificateRequest.
Подводя итог, моя ситуация была:
- Служба самообслуживания.
- Служба работает на HTTPS, на нестандартном порту (не 443, а 9000).
Это означало, что мне пришлось создать привязку SSL-сертификата для порта 9000 с помощью netsh.exe http add sslcert
. Ну, привязка была создана, но был улов. Я только нашел проблему после запуска netsh http show sslcert
только для проверки моей привязки:
IP:port : 0.0.0.0:9000
Certificate Hash : ...
Application ID : ...
Certificate Store Name : MY
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
-->Negotiate Client Certificate : Disabled
Претендент был последним свойством привязки, "Согласованный клиентский сертификат" , документированный здесь. По-видимому, по умолчанию это свойство отключено. Вам нужно включить его явно при создании привязки.
Повторное связывание с приведенным ниже выражением решает проблему:
netsh.exe http add sslcert ipport=0.0.0.0:9000 certhash=... appid=... certstorename=MY verifyclientcertrevocation=Enable VerifyRevocationWithCachedClientCertOnly=Disable UsageCheck=Enable clientcertnegotiation=Enable
Перед проверкой привязок я попробовал провести простую службу WCF в IIS и включить проверку подлинности сертификата клиента. Было очень любопытно видеть, что, хотя IIS не выдал CertificateRequest
, он по-прежнему не справился с 403.7. Даже IIS не создавал привязку с соответствующими параметрами.
В любом случае, теперь это работает, и вы можете это исправить.
Не забывайте, что конфигурация службы также изменилась (безопасность привязки), чтобы разрешить согласование сертификата:
<customBinding>
<binding name="CustomHttpBindingCustom" receiveTimeout="01:00:00">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="SecureConversation" requireSecurityContextCancellation="true">
<secureConversationBootstrap allowInsecureTransport="false" authenticationMode="MutualSslNegotiated" requireSecurityContextCancellation="true"></secureConversationBootstrap>
</security>
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>