2009-02-11 15 views
61

Obecnie jestem w trakcie integracji z systemem utworzonym przez firmę zewnętrzną. Ten system wymaga ode mnie wysłania żądania za pomocą XML/HTTPS. 3rd Party wysłać mi certyfikat i zainstalować goProblemy z WebClient + HTTPS

używam następujący kod:

using (WebClient client = new WebClient()) 
{ 
    client.Headers.Add(HttpRequestHeader.ContentType, "text/xml"); 

    System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding(); 
    var response = client.UploadData(address, "POST", encoding.GetBytes(msg)); 
} 

Ten kod zwraca następujący WebException:

Połączenie podstawowe zostało zamknięte: Nie można ustanowić relacja zaufania dla bezpiecznego kanału SSL/TLS.

UPDATE Ponieważ jest to serwer testowy pracuję przeciw, certyfikat nie jest zaufany i walidacja nie powiedzie ... Aby obejść ten w środowisku testowym/debugowania, tworzyć nowe ServerCertificateValidationCallback

ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(bypassAllCertificateStuff); 

i tu jest moje "fake" callback

private static bool bypassAllCertificateStuff(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error) 
{ 
    return true; 
} 

Czytaj więcej here i here

+4

+1 do aktualizacji z kodem używanym. Niezła szybka naprawa dla mnie z tego powodu. –

+0

To było bardzo użyteczne zamiast rejestrowania root'a CA skrzypka w moim dev-machine podczas debugowania webservices SSL! Właśnie wstawiłem #if DEBUG wokół części, która dodała fałszywą funkcję oddzwaniania, aby nie wstawiać jej do kodu produkcyjnego. – jishi

+0

Przejdź [tutaj.] (Http://forums.asp.net/p/1174025/1972251.aspx) – Lonzo

Odpowiedz

8

Dla wersji oryginalnej odpowiedzi VB.NET, tutaj (konwertery nie działają dobrze, gdy trzeba połączyć zdarzenia z operatorem "AddressOf"). 1-szy kod, który idzie przed użyciem WebClient() lub HttpWebRequest() obiektu:

ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf bypassAllCertificateStuff) 

..i przewodowe się kod metoda:

Private Shared Function bypassAllCertificateStuff(ByVal sender As Object, ByVal cert As X509Certificate, ByVal chain As X509Chain, ByVal [error] As System.Net.Security.SslPolicyErrors) As Boolean 
    Return True 
End Function 
68

Najkrótsza oznaczenie kodu, aby umożliwić wszystkich certyfikatów jest faktycznie:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

Działa również dobrze dla tego błędu. Nie trzeba dodawać, że powinieneś zapewnić implementację, która faktycznie sprawdza certyfikat i decyduje na podstawie informacji o certyfikacie, jeśli komunikacja jest bezpieczna. Do celów testowych użyj powyższego wiersza kodu.

+0

Bardzo pomocny w moich testach integracyjnych! –

-1

Spróbuj tego, to działa:

class Ejemplo 
{ 
    static void Main(string[] args) 
    { 
     string _response = null; 
     string _auth = "Basic"; 
     Uri _uri = new Uri(@"http://api.olr.com/Service.svc"); 

     string addres = @"http://api.olr.com/Service.svc"; 
     string proxy = @"http://xx.xx.xx.xx:xxxx"; 
     string user = @"platinum"; 
     string pass = @"01CFE4BF-11BA"; 


     NetworkCredential net = new NetworkCredential(user, pass); 
     CredentialCache _cc = new CredentialCache(); 

     WebCustom page = new WebCustom(addres, proxy); 
     page.connectProxy(); 

     _cc.Add(_uri, _auth, net); 

     page.myWebClient.Credentials = _cc; 

     Console.WriteLine(page.copyWeb()); 
    } 

} 

public class WebCustom 
{ 
     private string proxy; 
     private string url; 
     public WebClient myWebClient; 
     public WebProxy proxyObj; 
     public string webPageData; 


     public WebCustom(string _url, string _proxy) 
     { 
      url = _url; 
      proxy = _proxy; 
      myWebClient = new WebClient(); 
     } 

     public void connectProxy() 
     { 
      proxyObj = new WebProxy(proxy, true); 
      proxyObj.Credentials = CredentialCache.DefaultCredentials; 
      myWebClient.Proxy = proxyObj; 
     } 

     public string copyWeb() 
     { return webPageData = myWebClient.DownloadString(url); } 
} 
+2

Czy możesz wyjaśnić, w jaki sposób Twoje rozwiązanie rozwiązuje problem HTTP_S_? –