#c# #wcf #ssl
#c# #wcf #ssl
Вопрос:
У меня есть служба WCF, которая требует аутентификации клиента с помощью сертификата.
У меня есть простое консольное приложение, которое использует этот WCF.
У меня есть 2 клиентских сертификата, с первым консольные приложения работают идеально, а со вторым оно возвращает эту ошибку:
System.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden.
Как я вижу в журналах IIS, это 403.7.
Оба сертификата установлены в одном хранилище и оба имеют одинаковые разрешения в области Управления закрытыми ключами для пользователя, который запускает консольное приложение.
Оба сертификата имеют:
- Закрытый ключ
- Использование ключа: цифровая подпись, неотказуемость, шифрование ключа, шифрование данных (f0)
- Расширенное использование ключа: аутентификация клиента (1.3.6.1.5.5.7.3.2)
- Являются действительными и имеют тот же путь сертификации
Есть идеи?
Обновить
Если я активирую ведение журнала SCHANNEL, когда я использую сертификат с ошибкой, в программе просмотра событий мы видим эту ошибку:
РЕШАЕМАЯ
Проблема заключалась в том, что мы получали сертификат с помощью:
X509FindType.FindBySubjectName
И с объектом, который мы используем, есть по крайней мере еще 3 сертификата, которые содержат этот объект.
Тогда сертификат, который мы получаем, неверен, мы меняем код, чтобы использовать
X509FindType.FindBySubjectDistinguishedName или X509FindType.FindByThumbprint
И теперь получает правильный сертификат клиента и работает.
Комментарии:
1. Я только предполагаю, что ваш запрос не может пройти проверку подлинности через службу WCF, потому что, возможно, он размещен внутри приложения aspnet?
2. Если оба сертификата действительны, имеют одинаковый путь сертификации и настроены одинаково, то проблема, скорее всего, может быть связана с конфигурацией WCF. Возможно, вы могли бы опубликовать соответствующие разделы файла app.config для проверки (<endpointBehaviors><behavior><ClientCredentials><ClientCertificate findValue=»»)
3. У меня есть пользовательская привязка: <httpsTransport manualAddressing=»false» MaxBufferPoolSize=»524288″ maxReceivedMessageSize=»65536″ allowCookies =»false» AuthenticationScheme=»Anonymous» bypassProxyOnLocal =»false» HostNameComparisonMode=»StrongWildcard» keepAliveEnabled=»true» MaxBufferSize=»65536″ proxyAuthenticationScheme=»Анонимный» realm=»» TransferMode=»Буферизованный» unsafeConnectionNtlmAuthentication=»ложный» useDefaultWebProxy=»истинный» requireClientCertificate=»истинный»/>
4. Я думаю, клиенту все еще необходимо идентифицировать сертификат для использования, указав: (<endpointBehaviors><поведение><Клиентские учетные записи><ClientCertificate findValue=»»)
5. Я назначаю сертификат клиента в коде, X509Store X509Store = новый X509Store(имя хранилища. Мой, местоположение хранилища. LocalMachine); X509Store. Открыть (OpenFlags. Доступно только для чтения); X509Certificate2Collection x509Certificate2Collection = X509Store. Сертификаты. Найти(X509FindType.FindBySubjectName, text, true); клиент. Клиентские учетные записи. Сертификат клиента. Сертификат = x509Certificate2Collection[0];
Ответ №1:
Это зависит от режима проверки сертификата сервера. Например, когда мы используем CertificationValidationMode=Custom, мы могли бы указать пользовательский класс X509validator, который реализует
System.IdentityModel.Selectors.X509CertificateValidator
Возможно, у него была пользовательская проверка при обработке сертификата клиента.
Если CertificateionValidationMode=ChainTrust, вы должны убедиться, что клиент хранится в правильной области хранилища и в той же цепочке с сертификатом сервера.
Каков режим проверки сертификата сервера?
Не стесняйтесь обращаться ко мне, если я могу чем-нибудь помочь.
Комментарии:
1. У нас на сервере есть пользовательское поведение, которое получает сертификат и проверяет, но поведение с этим сертификатом никогда не выполняется. Служба возвращает ошибку до того, как поведение будет выполнено.