Faites appel à Https en utilisant HttpClient

j'ai utilisé HttpClient pour faire des appels WebApi en utilisant C#. Semble soigné et rapide par rapport à WebClient . Cependant je suis coincée en faisant des appels Https .

Comment puis-je faire ci-dessous le code pour faire des appels Https ?

HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://foobar.com/");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/xml"));

var task = httpClient.PostAsXmlAsync<DeviceRequest>(
                "api/SaveData", request);

EDIT 1: Le code ci-dessus fonctionne très bien pour faire des appels http. Mais quand je change le schéma en https, ça ne marche pas. Voici l'erreur obtenue:

le lien sous-jacent a été fermé: ne pouvait pas établir la confiance relation pour la voie de communication protégée SSL/TLS.

EDIT 2: Modifier le schéma en https est la première étape.

Comment puis-je fournir le certificat et la clé publique / privée avec C# demande.

111
demandé sur Abhijeet 2014-03-07 17:40:12

10 réponses

si le serveur ne supporte que la version TLS supérieure comme TLS 1.2 seulement, il échouera quand même à moins que votre PC client ne soit configuré pour utiliser la version TLS supérieure par défaut. Pour résoudre ce problème, ajoutez ce qui suit dans votre code.

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

modifier votre code d'exemple, ce serait

HttpClient httpClient = new HttpClient();   

//specify to use TLS 1.2 as default connection
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

httpClient.BaseAddress = new Uri("https://foobar.com/");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

var task = httpClient.PostAsXmlAsync<DeviceRequest>("api/SaveData", request);
119
répondu Ronald Ramos 2015-10-12 23:39:32

spécifiez simplement HTTPS dans L'URI.

new Uri("https://foobar.com/");

Foobar.com vous aurez besoin d'un certificat SSL fiable ou vos appels échoueront avec une erreur non fiable.

MODIFIER la Réponse: ClientCertificates avec HttpClient

WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 certificate = GetMyX509Certificate();
handler.ClientCertificates.Add(certificate);
HttpClient client = new HttpClient(handler);

EDIT Answer2: si le serveur sur lequel vous vous connectez a désactivé SSL, TLS 1.0 et 1.1 et que vous êtes toujours en cours D'exécution. ci-dessous) vous devez faire un choix

  1. Upgrade to .Net 4.6+ ( supporte TLS 1.2 par défaut )
  2. ajouter des modifications au Registre pour donner l'instruction 4.5 de se connecter sur TLS1.2 (Voir: Salesforce writeup for compat and keys to change OR checkout IISCrypto voir Ronald Ramos answer comments )
  3. ajouter le code d'application configurer manuellement .NET pour se connecter sur TLS1.2 (Voir Ronald Ramos réponse )
114
répondu felickz 2017-05-23 11:47:20

votre code doit être modifié de cette façon:

httpClient.BaseAddress = new Uri("https://foobar.com/");

il suffit d'utiliser le schéma URI https: . Il y a une page utile ici sur MSDN à propos des connexions HTTP sécurisées. En effet:

utiliser le schéma https: URI

le protocole HTTP définit deux schémas URI:

http: utilisé pour les connexions non cryptées.

https: utilisé pour les connexions sécurisées qui doivent être cryptées. Cette option utilise des certificats numériques et les autorités de certification pour vérifier que le serveur est bien qui il prétend être.

de plus, considérer que les connexions HTTPS utilisent un certificat SSL. Assurez-vous que votre connexion sécurisée possède ce certificat, sinon les requêtes échoueront.

EDIT:

Le code ci-dessus fonctionne très bien pour faire des appels http. Mais quand je change le schéma de https, il ne fonctionne pas, permettez-moi d'afficher le message d'erreur.

ça veut dire quoi ça ne marche pas? Les demandes échouent? Une exception est lancée? Clarifiez votre question.

si les requêtes échouent, alors la délivrance doit être le certificat SSL.

pour corriger l'émission, vous pouvez utiliser la classe HttpWebRequest et ensuite sa propriété ClientCertificate . En outre, vous pouvez trouver ici un exemple utile sur la façon de faire une demande HTTPS en utilisant le certificat.

un exemple est le suivant (comme indiqué dans la page MSDN liée avant):

//You must change the path to point to your .cer file location. 
X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\mycert.cer");
// Handle any certificate errors on the certificate from the server.
ServicePointManager.CertificatePolicy = new CertPolicy();
// You must change the URL to point to your Web server.
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://YourServer/sample.asp");
Request.ClientCertificates.Add(Cert);
Request.UserAgent = "Client Cert Sample";
Request.Method = "GET";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
13
répondu Alberto Solano 2015-01-27 14:49:54

j'ai eu le même problème lors de la connexion à GitHub, qui nécessite un agent utilisateur. Il est donc suffisant de fournir ce certificat plutôt que de générer un certificat

var client = new HttpClient();

client.BaseAddress = new Uri("https://api.github.com");
client.DefaultRequestHeaders.Add(
    "Authorization",
    "token 123456789307d8c1d138ddb0848ede028ed30567");
client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add(
    "User-Agent",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
6
répondu Carlo V. Dango 2018-07-31 01:42:01

le simple fait de spécifier HTTPS dans l'URI devrait faire l'affaire.

httpClient.BaseAddress = new Uri("https://foobar.com/");

si la requête fonctionne avec HTTP mais échoue avec HTTPS alors il s'agit très certainement d'une délivrance de certificat . Assurez-vous que l'appelant fait confiance à l'émetteur du certificat et vérifier que le certificat n'est pas expiré. Un moyen rapide et facile de vérifier qui est d'essayer de faire la requête dans un navigateur.

Vous pouvez également vouloir vérifier sur le serveur (si c'est le vôtre et / ou si vous pouvez) qu'il est défini pour servir correctement les requêtes HTTPS.

4
répondu Crono 2014-03-07 14:04:42

quand se connecter à https j'ai eu cette erreur aussi, j'ajoute cette ligne avant HttpClient httpClient = new HttpClient(); et se connecter avec succès:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

je le sais de Cette Réponse et Autre Réponse et le commentaire mentionne:

c'est un hack utile dans le développement donc mettre un #if DEBUG #endif statement autour c'est le moins que vous devriez faire pour rendre cela plus sûr et arrêter cela se retrouvant en production

D'ailleurs, je n'ai pas essayé la méthode dans une autre réponse qui utilisent new X509Certificate() ou new X509Certificate2() pour faire un certificat, Je ne suis pas sûr que simplement créer par new() fonctionnera ou pas.

EDIT: Quelques Références:

créer un certificat de serveur auto-signé dans IIS 7

Certificats SSL d'importation et D'exportation en IIS 7

Convert .pfx .cer

les Meilleures pratiques pour l'utilisation de ServerCertificateValidationCallback

je trouve que la valeur de L'empreinte du pouce est égale à x509certificate.GetCertHashString() :

récupérer l'empreinte du pouce d'un certificat

4
répondu yu yang Jian 2018-07-21 10:00:48

j'ai aussi eu l'erreur:

le lien sous-jacent a été fermé: ne pouvait pas établir la confiance relation pour la voie de communication protégée SSL/TLS.

... avec un Xamarin formulaires Android - application de ciblage tenter de demander des ressources auprès d'un fournisseur D'API qui nécessite TLS 1.3.

la solution était de mettre à jour le projet configuration pour permuter le client http "managed" (.NET) de Xamarin (qui ne supporte pas TLS 1.3 À partir des formulaires v2 de Xamarin).5), et à la place utiliser le client natif android.

c'est un simple projet de bascule dans visual studio. Voir la capture d'écran ci-dessous.

  • Propriétés Du Projet
  • Options Android
  • avancé
  • article de la liste
  • Change " HttpClient la mise en œuvre" à "Android"
  • Changement SSL/TLS mise en œuvre de "Native TLS 1.2+"

enter image description here

1
répondu MSC 2018-05-02 18:15:29

vous pouvez essayer d'utiliser le paquet ModernHttpClient Nuget: après avoir téléchargé le paquet, vous pouvez le mettre en œuvre comme ceci:

 var handler = new ModernHttpClient.NativeMessageHandler()
        {
            UseProxy = true,
        }; ;


        handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
        handler.PreAuthenticate = true;
        HttpClient client = new HttpClient(handler);
0
répondu uchenna nnodim 2016-08-03 04:17:50

ajouter les déclarations suivantes à votre classe:

public const SslProtocols _Tls12 = (SslProtocols)0x00000C00;
public const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12;

après:

var client = new HttpClient();

et:

ServicePointManager.SecurityProtocol = Tls12;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 /*| SecurityProtocolType.Tls */| Tls12;

heureux? :)

0
répondu Greg Stawski 2018-06-27 11:45:09

pour erreur:

le lien sous-jacent a été fermé: ne pouvait pas établir la confiance relation pour la voie de communication protégée SSL/TLS.

je pense que vous devez accepter le certificat inconditionnellement avec le code suivant

ServicePointManager.ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

comme oppositionnel a écrit dans sa réponse à la question .net client se connectant à ssl API Web .

-3
répondu Nemanja Simović 2018-01-19 15:25:10