Comment utiliser WebRequest pour accéder à un site crypté SSL via https?


116

J'écris un programme qui lit le contenu d'une URL fournie par l'utilisateur. Mon problème est dans le code qui ressemble à ceci:

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

Et c'est cassant si l' URL fournie est une URL "https: //". Quelqu'un peut-il m'aider à modifier ce code afin qu'il fonctionne avec le contenu crypté SSL. Merci.

Réponses:


175

Vous le faites correctement, mais les utilisateurs peuvent fournir des URL à des sites sur lesquels des certificats SSL non valides sont installés. Vous pouvez ignorer ces problèmes de certificat si vous mettez cette ligne avant de faire la requête Web réelle:

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

AcceptAllCertificationsest défini comme

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
Merci pour cette réponse! Pour éviter un code inutile, je l'ai utilisé comme ceci: ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
Charles Ouellet

4
Merci, vous m'avez aidé monsieur. F # facilite les choses:ServicePointManager.ServerCertificateValidationCallback <- Security.RemoteCertificateValidationCallback (fun _ _ _ _ -> true)
David Grenier

2
@Charles Ouellet Je suppose que je suis encore plus paresseux que toi, (a, b, c, d) => true
Despertar

24
Je préfère+= delegate { return true; }
vkrzv

2
Soyez conscient des risques potentiels associés à cette approche. Voir stackoverflow.com/a/6613434/2969615 pour plus d'informations.
Joe Coyle

19

Ce lien vous intéressera: http://msdn.microsoft.com/en-us/library/ds8bxk2a.aspx

Pour les connexions http, les classes WebRequest et WebResponse utilisent SSL pour communiquer avec les hôtes Web qui prennent en charge SSL. La décision d'utiliser SSL est prise par la classe WebRequest, en fonction de l'URI qui lui est donné. Si l'URI commence par "https:", SSL est utilisé; si l'URI commence par "http:", une connexion non chiffrée est utilisée.


Excellent lien. C'est une distinction importante.
DanM7

1
Votre réponse implique que le code de la question devrait fonctionner?
Rowland Shaw le

18

Celui-ci a fonctionné pour moi:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

1
La valeur par défaut est "Ssl2 | Tls". J'avais seulement activé Tls 1.1 et 1.2 sur mon serveur. Cela a en effet résolu le problème! Pour LetsEncrypt avec nginX sous linux, les protocoles sont définis ici: /etc/letsencrypt/options-ssl-nginx.conf
Jerther

Je pense qu'il s'agit d'un problème différent. Il ne s'agit pas de certificats invalides mais de versions TLS supérieures.
wp78de

J'obtenais "Une connexion existante a été fermée de force par l'hôte distant" et cette solution a fonctionné pour moi
oamilkar

Notez qu'il s'agit d'une configuration globale, vous n'avez donc à le faire qu'une seule fois et non à chaque fois que vous configurez la demande.
Chad Hedgcock

Puis-je faire cela pour une seule demande d'une manière ou d'une autre? Il semble que ServicePointManager est une chose plutôt globale ...
wexman
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.