2011-07-01 14 views
11

Al hacer una llamada a un servicio web que se ejecuta en un servidor mediante HTTPS mi solicitud tiros un System.NET.WebException con el mensaje "La conexión subyacente se cerró: ¿Podría no establecer una relación de confianza con el servidor remoto ". No estoy seguro de cómo solucionar este problema y hacer la llamada con éxito.System.NET.WebException arrojado al consumir un servicio web a través de HTTPS

+0

¿Puede acceder a la URL a través de un navegador? Si es así, ¿el navegador le advierte que el certificado no es válido? – dlev

Respuesta

17

Después de algunas investigaciones, encontré un artículo del blog de Jan Tielens que explica lo que está ocurriendo y una solución para mi problema:

Cuando navega a un sitio HTTPS, es probable que obtener una ventana de diálogo que le pregunta si desea confiar en el certificado proporcionado por el servidor web. Por lo tanto, el usuario maneja la responsabilidad de aceptar el certificado. Regresemos al escenario del servicio web, si desea invocar un servicio web ubicado en un servidor web que utiliza SSL y HTTPS, existe un problema. Cuando realiza la llamada desde el código, no hay ventana de diálogo que se levante, y preguntando si confía en el certificado (por suerte, porque esto sería bastante feo en los escenarios del lado del servidor); probablemente obtendrá siguiente excepción:

Una excepción no controlada del tipo System.Net.WebException se produjo en System.dll
Información adicional: El conexión subyacente se cerró: No se pudo establecer relación de confianza con servidor remoto.

Pero hay una solución para este problema , puede resolver esto en su código mediante la creación de su propio CertificatePolicy clase (que implementa la interfaz ICertificatePolicy ). En esta clase usted tiene que escribir su propia función CheckValidationResult que tiene que volver true o false, al igual que presionaría sí o no en el ventana de diálogo. Para los propósitos de desarrollo que he creado la siguiente clase que acepta todos los certificados, por lo que no voy a conseguir el desagradable WebException más:

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

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

Como se puede ver la función CheckValidationResult siempre devuelve true, por lo que todos los certificados serán confiables. Si desea hacer esta clase un poco más seguro, puede agregar comprobaciones adicionales usando el parámetro X509Certificate por ejemplo. Para utilizar esta CertificatePolicy, podrás tiene que decirle al ServicePointManager utilizarlo:

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

Esto se debe hacer (una vez durante el ciclo de vida de aplicaciones ) antes de hacer la llamada a su servicio web

3

Si está utilizando un certificado SSL autofirmado o un certificado SSL no confiable, puede indicarle a su aplicación que lo ignore (si realmente desea ignorarlo). p.ej.

ServicePointManager.ServerCertificateValidationCallback = _ 
     new RemoteCertificateValidationCallback(IgnoreSelfSSL) 

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

Puede colocar la devolución de llamada en cualquier lugar que se golpee antes de ejecutar su llamada de servicio.

1

Las sugerencias dadas en las respuestas se deben usar solo para probar. Para la aceptación/producción, debe tener el certificado WS instalado en la máquina que realiza la llamada a WS, y realizar la validación del certificado antes de llamar a WS: caducidad, asunto, etc. Luego puede agregar este certificado a la solicitud de WS a través del SoapHttpClientProtocol.Proxy.ClientCertificates.

Cuestiones relacionadas