При обращении к веб-службе, запущенной на сервере с использованием HTTPS, мое приложение выдает сообщение System.Net.WebException с сообщением "Основное соединение было закрыто: не удалось установить доверительные отношения с удаленным сервером". Я не уверен, как обойти эту проблему и успешно выполнить вызов.
Исключение System.Net.WebException при использовании веб-службы через HTTPS
Ответ 1
После некоторого исследования я нашел запись в блоге Jan Tielens, в которой объясняется, что происходит, и обходной путь для моей проблемы:
Когда вы переходите на сайт HTTPS, вы, вероятно, получите диалоговое окно с запросом, хотите ли вы доверять сертификату, предоставленному веб-сервером. Таким образом, ответственность за принятие сертификата обрабатывается пользователем. Вернитесь к сценарию webservice, если вы хотите вызвать веб-сервис, расположенный на веб-сервере, который использует 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();
Это должно быть сделано (один раз в течение жизненного цикла приложения), прежде чем вызов вашего веб-сервиса.
Ответ 2
Если вы используете самоподписанный SSL-сертификат или ненадежный SSL-сертификат, вы можете сказать своему приложению игнорировать его (если вы действительно хотите его игнорировать). например.
ServicePointManager.ServerCertificateValidationCallback = _
new RemoteCertificateValidationCallback(IgnoreSelfSSL)
public bool IgnoreSelfSSL(ServicePoint sp, X509Certificate cert,WebRequest req, int problem) {
return true;
}
Вы можете поместить обратный вызов в любом месте, которое будет удалено до выполнения вашего служебного вызова.
Ответ 3
Рекомендации, приведенные в ответах, следует использовать только для тестирования. Для принятия/производства у вас должен быть установлен WS-сертификат на вызов компьютера на WS и проверка сертификата перед вызовом WS-expiration, subject и т.д. Затем вы можете добавить этот сертификат к WS-запросу через SoapHttpClientProtocol.Proxy.ClientCertificates.