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.