jueves, 29 de noviembre de 2007

Error: No se puede establecer una relación de confianza para el canal seguro SSL/TLS

Hace unos dias, empezamos los trabajos de construccion para un proyecto en que estoy, basicamente, aplicaciones que correran en un entorno HTTPS, y tuvimos un problema al tratar de acceder a una lista del Sharepoint que se encuentra en ese Site que trabaja con certificados.
Basicamente el mensaje de error es el siguiente:

System.Net.WebException: Se ha terminado la conexión: No se puede establecer una relación de confianza para el canal seguro SSL/TLS. ---> System.Security.Authentication.AuthenticationException: El certificado remoto no es válido según el procedimiento de validación.

Pase todo un dia buscando informacion y no encontraba nada, pero luego tanto un amigo mio encontro la forma de lograrlo.
Pero antes de dar la solucion voy a tratar de explicar un poco que es lo que pasa.
Simplemente el error se debe a que por tratarse de un HTTPS, al tratar de acceder a algun contenido entonces me pide un certificado y como no tengo entonces me bota ese error.
Entonces por alli atacaremos el problema:

Este es el codigo que yo uso para acceder a una lista y sacar sus valores:

XmlDocument xmlDoc = new System.Xml.XmlDocument();
XmlElement viewFields = xmlDoc.CreateElement("ViewFields");
viewFields.InnerXml = "";
portal.Lists listService = null;
listService = new portal.Lists();
listService.Credentials = new System.Net.NetworkCredential("user", "password", "dominio");
listService.PreAuthenticate = true;
string listGuid = (string)"{AE348D4B-D88C-46B3-A809-B4663C4C7CB0}";
XmlNode itemCollection = listService.GetListItems(listGuid, string.Empty, null, viewFields, "0", null, string.Empty);
return itemCollection;


Para esto portal es un referencia Web al webservice del Sharepoint.
algo como esto: https://MyServer/_vti_bin/lists.asmx

Si esto es probado en test funciona de maravillas, pero cuando queremos consumir ese webservices nos da un error como el mostrado anteriormente.

Bueno sin mas vueltas que dar, agreguemos esta linea

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
CredentialCache cache = new CredentialCache();


Espero que esto soluciona sus problemas.
Saludos

11 comentarios:

Anónimo dijo...

Hola Marco:

Podrias indicarme el nombre del arhivo y ubicacion donde ingreso las lineas de codigo que haces referencia

Gracias!

Marco Diaz dijo...

Hola.
Disculpandome por la demora de la respuesta.
Este codigo se coloca antes de hacer una llamada a webservices.
y por omision no coloque una funcion.

public static bool ValidateServerCertificate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
Espero que aun sirva la respuesta.
Al agregar este codigo tienes que apregar algunas referencias.
Cuidate.

Anónimo dijo...

Que tal Amigo

Muchas gracias por la información publicada me sirvio de mucho ya que tenia un error similar

saludos
ok

Anónimo dijo...

Excelente solución, gracias!
Un saludo desde Uruguay...

Unknown dijo...

Muchisimas gracias!
Me has salvado la vida con un certificado que me estaba volviendo loco.

Un saludo

Anónimo dijo...

Simplemente gracias.
Quizas a alguien le sirva lo siguiente (traduccion a VB).

Public Shared Function ValidateServerCertificate(ByVal sender As [Object], ByVal certificate As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
Return True
End Function


Dim instance As ServicePointManager
instance.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate)
Dim credential As CredentialCache = New CredentialCache()

Saludos desde Uruguay.

Anónimo dijo...

Muchas gracias desde España.

Si alguien necesita ver todas las librerias o más información: http://fabioscagliola.spaces.live.com/blog/cns!919F8FCDE3DC9AC4!154.entry

Anónimo dijo...

Muchas gracias desde España.

En VB no olvidar importar:

Imports System.Net
Imports System.Net.Security

El codigo previa antes de llamar al servicio web:
ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate)
Dim credential As CredentialCache = New CredentialCache()

Anónimo dijo...

Edson Veneros, Desde Bolivia: Excelente, muchas gracias, me sirvio de mucho, sigue adelante

Cesar Castro dijo...

Excelente solución, muchas gracias

Unknown dijo...

Excelente TIP, muchas gracias. Funciona perfectamente