Исключение System.Net.WebException при использовании веб-службы по протоколу HTTPS. - PullRequest
11 голосов
/ 01 июля 2011

При вызове веб-службы, работающей на сервере с использованием HTTPS, мое приложение генерирует исключение System.Net.WebException с сообщением «Основное соединение было закрыто: не удалось установить доверительные отношения с удаленным сервером».Я не уверен, как обойти эту проблему и успешно сделать звонок.

Ответы [ 3 ]

17 голосов
/ 01 июля 2011

После некоторого исследования я нашел запись в блоге Jan Tielens , которая объясняет, что происходит, и способ решения моей проблемы:

Когда вы заходите на сайт HTTPS, вы, вероятно, получаете диалоговое окно с вопросом, хотите ли вы доверять сертификату, предоставленному веб-сервером. Таким образом, ответственность за принятие сертификата несет пользователь. Давайте вернемся к сценарию веб-службы, если вы хотите вызвать веб-службу, расположенную на веб-сервере, который использует SSL и HTTPS, существует проблема. Когда вы делаете вызов из кода, диалоговое окно не появляется и не спрашиваете, доверяете ли вы сертификату (к счастью, это будет довольно уродливо в серверных сценариях); вероятно, вы получите следующее исключение:

Произошло необработанное исключение типа System.Net.WebException в System.dll
Дополнительная информация: основной соединение было закрыто: не удалось установить доверительные отношения с удаленный сервер.

Но для этого есть решение проблема, вы можете решить это в своем код, создавая свой собственный CertificatePolicy класс (который реализует ICertificatePolicy интерфейс). В этом классе вы будете должен написать свой собственный CheckValidationResult функция, которая должен вернуть true или false, как вы будет нажимать да или нет в диалоге окно. В целях развития я создал следующий класс, который принимает все сертификаты, поэтому вы не будете получите больше противного WebException:

public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
{
    public TrustAllCertificatePolicy() { }

    public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int problem)
    {
        return true;
    }
}

Как вы можете видеть CheckValidationResult функция всегда возвращает true, поэтому все сертификаты будут быть доверенным. Если вы хотите сделать это класс немного более безопасным, вы можно добавить дополнительные проверки, используя X509Certificate параметр, например. Чтобы использовать это CertificatePolicy, вы будете должен сказать ServicePointManager чтобы использовать это:

System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

Это должно быть сделано (один раз во время жизненный цикл приложения) до принятия звонок на ваш веб-сервис.

3 голосов
/ 01 июля 2011

Если вы используете самозаверяющий SSL-сертификат или недоверенный SSL-сертификат, вы можете указать приложению игнорировать его (если вы действительно хотите его игнорировать).например,

ServicePointManager.ServerCertificateValidationCallback = _
      new RemoteCertificateValidationCallback(IgnoreSelfSSL)

public bool IgnoreSelfSSL(ServicePoint sp, X509Certificate cert,WebRequest req, int problem) { 
   return true; 
}

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

1 голос
/ 02 июля 2011

Советы, данные в ответах, должны использоваться только для тестирования . Для принятия / производства у вас должен быть установлен сертификат WS на машине, выполняющей вызов WS, и выполнить проверку сертификата перед вызовом WS - срок действия, субъект и т. Д. Затем вы можете добавить этот сертификат в запрос WS через SoapHttpClientProtocol.Proxy.ClientCertificates .

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