Come si utilizza WebRequest per accedere a un sito crittografato SSL utilizzando https?


116

Sto scrivendo un programma che legge il contenuto da un URL fornito dall'utente. Il mio problema è nel codice che va qualcosa del genere:

Uri uri = new Uri(url);
WebRequest webRequest = WebRequest.Create(uri);
WebResponse webResponse = webRequest.GetResponse();
ReadFrom(webResponse.GetResponseStream());

E questo non funziona se l' URL fornito è un URL "https: //". Qualcuno può aiutarmi a modificare questo codice in modo che funzioni con contenuti crittografati SSL. Grazie.

Risposte:


175

Lo stai facendo nel modo corretto, ma gli utenti potrebbero fornire URL a siti in cui sono installati certificati SSL non validi. Puoi ignorare questi problemi di certificato se inserisci questa riga prima di effettuare l'effettiva richiesta web:

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

dove AcceptAllCertificationsè definito come

public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}

41
Grazie per questa risposta! Per evitare del codice inutile l'ho usato così: ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
— Charles Ouellet

4
Grazie, mi hai aiutato signore. Fa # rende tutto più semplice:ServicePointManager.ServerCertificateValidationCallback <- Security.RemoteCertificateValidationCallback (fun _ _ _ _ -> true)
— David Grenier

2
@Charles Ouellet Immagino di essere ancora più pigro di te, (a, b, c, d) => true
— Despertar

24
Preferisco+= delegate { return true; }
— vkrzv

2
Sii consapevole dei potenziali rischi associati a questo approccio. Vedi stackoverflow.com/a/6613434/2969615 per ulteriori informazioni.
— Joe Coyle

19

Questo collegamento ti interesserà: http://msdn.microsoft.com/en-us/library/ds8bxk2a.aspx

Per le connessioni http, le classi WebRequest e WebResponse utilizzano SSL per comunicare con host web che supportano SSL. La decisione di utilizzare SSL viene presa dalla classe WebRequest, in base all'URI fornito. Se l'URI inizia con "https:", viene utilizzato SSL; se l'URI inizia con "http:", viene utilizzata una connessione non crittografata.


Ottimo collegamento. Questa è una distinzione importante.
— DanM7

1
La tua risposta implica che il codice nella domanda dovrebbe funzionare?
— Rowland Shaw

18

Questo ha funzionato per me:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

1
Il valore predefinito è "Ssl2 | Tls". Avevo abilitato solo Tls 1.1 e 1.2 sul mio server. Questo in effetti ha risolto il problema! Per LetsEncrypt con nginX su Linux, i protocolli sono definiti qui: /etc/letsencrypt/options-ssl-nginx.conf
— Jerther

Credo che si tratti di una questione diversa. Non si tratta di certificati non validi, ma di versioni TLS superiori.
— wp78de

Stavo ricevendo "Una connessione esistente è stata chiusa forzatamente dall'host remoto" e questa soluzione ha funzionato per me
— oamilkar

Nota che questa è una configurazione globale, quindi devi farlo solo una volta e non ogni volta che imposti la richiesta.
— Chad Hedgcock

Posso farlo per una singola richiesta in qualche modo? Sembra che ServicePointManager sia una cosa piuttosto globale ...
— wexman
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.