При обращении к веб-службе, запущенной на сервере с использованием 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.