web-dev-qa-db-fra.com

L'authentification C # a échoué car la partie distante a fermé le flux de transport

Je tiens à souligner que j'ai beaucoup cherché cela sans solution. J'ai donc créé une boucle qui lancera listBox2 qui contient des liens, créant à chaque fois une requête http GET afin d'accéder au code source complet.

Mon code:

 private void button4_Click(object sender, EventArgs e)
    {
        try
        {
            for (int i = 0; i < listBox2.Items.Count; i++)
            {
                code(listBox2.Items[i].ToString() + "\'");
                //await PutTaskDelay();
                //Console.WriteLine(listBox2.Items[i].ToString());
                if (VarrileKeeper.s.ToLower().Contains("mysql"))
                {
                    Console.WriteLine("possitive " + listBox2.Items[i].ToString());
                }
            }
        }
        catch (Exception Fejl)
        {
            Console.WriteLine(Fejl);
        }
    }


 public static String code(string Url)
    {

        System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };


        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(Url);
        myRequest.MaximumAutomaticRedirections = 4;
        myRequest.MaximumResponseHeadersLength = 4;
        myRequest.Credentials = CredentialCache.DefaultCredentials;

        myRequest.Method = "GET";

        WebResponse myResponse = myRequest.GetResponse();


        StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
        string result = sr.ReadToEnd();
        sr.Close();
        myResponse.Dispose();
        myResponse.Close();
        VarrileKeeper.s = result;
        return result;
    }

L'erreur ci-dessous est déclenchée lorsque la boucle atteint plusieurs URL par exemple ( http://www.memphremagog.org/fr/lexique.php?id=32 ). La chose étrange est que si je supprime la boucle et que je fais une requête http GET sur ce site, tout fonctionne très bien.

Une première exception de type "System.Net.WebException" s'est produite dans System.dll System.Net.WebException: la connexion sous-jacente a été fermée: une erreur inattendue s'est produite lors d'un envoi. ---> System.IO.IOException: l'authentification a échoué car la partie distante a fermé le flux de transport.

Je ne pense pas que ce soit un problème avec le certificat car sinon j'obtiendrais toujours une erreur sur http://www.memphremagog.org/fr/lexique.php?id=32 quand j'ai supprimé le boucle.

Toutes les suggestions sont appréciées.

11
Taco2

L'url zvoxaudio.com, d'après vos commentaires, est assez délicat. Ils ont une détection de bot pour ajouter des articles à un panier. Le lien que vous avez utilisé spécifiquement ne semble pas fonctionner quoi qu'il arrive, je pense qu'il utilise un identifiant d'élément expiré; J'ai pu l'utiliser en mettant à jour l'identifiant en 4007001 et en le changeant en 'https'. Ce lien ajoute cependant un article au panier et le site n'autorise pas les bots à ajouter des articles à un panier, le site renvoie une erreur 400 avec cette clé: valeur dans les en-têtes:

X-Error-Message: Bots are not allowed to add items to cart

Essayez d'ajouter un UserAgent à votre demande comme ceci:

  myRequest.UserAgent = "Nada";

Avec ces quelques changements, le lien ZVOXAUDIO fonctionne!

Si vous souhaitez conserver l'URL en tant que demande "https", ajoutez-la simplement à votre code.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

Ceci est nécessaire car ZVOXAUDIO ne prend pas en charge TLS 1.0 ou les protocoles antérieurs. Si la version de .NET que vous utilisez ne prend pas en charge TLS 1.2, vous pouvez utiliser SecurityProtocolType.Tls11 car ZVOXAUDIO prend toujours en charge TLS 1.1.

Mais puisque, vraisemblablement, vous essayez de faire fonctionner cela sur autant de sites que possible, vous ne voulez probablement pas autoriser uniquement TLS 1.2, car les serveurs plus anciens peuvent ne pas le prendre en charge. Je définirais votre protocole de sécurité comme ceci:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 |
                                       SecurityProtocolType.Tls11 |
                                       SecurityProtocolType.Tls |
                                       SecurityProtocolType.Ssl3;

À titre de suggestion, vous pouvez définir le rappel de validation du certificat du serveur et le protocole de sécurité en dehors de votre boucle car il s'agit d'un paramètre statique pour toutes les demandes. De plus, si vous utilisez la syntaxe C # en utilisant, la méthode Dispose se charge de fermer et de supprimer vos variables WebResponse et StreamReader pour vous. Et C # a réintroduit "var" dans .NET 3.0, vous voudrez peut-être commencer à l'adopter, c'est-à-dire en supposant que vous utilisez le framework 3.0 ou plus récent. Si vous voulez voir à quoi cela ressemblerait, regardez ci-dessous.

Assurez-vous d'avoir ces utilisations:

using System;
using System.IO;
using System.Net;

Ensuite, mettez ces deux lignes dans le constructeur statique de votre formulaire ou objet, je suppose que vous utilisez un formulaire en ce moment:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

Vos deux méthodes ressembleraient alors à ceci:

private void button4_Click(object sender, EventArgs e)
{
  try
  {
    for (var i = 0; i < listBox2.Items.Count; i++)
    {
      var response = Code(listBox2.Items[i].ToString() + "\'");
      if (response.ToLower().Contains("mysql"))
      {
        Console.WriteLine("positive " + listBox2.Items[i].ToString());
      }
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex.Message);
  }
}


public static string Code(string url)
{
  var webRequest = (HttpWebRequest)WebRequest.Create(url);
  webRequest.MaximumAutomaticRedirections = 4;
  webRequest.MaximumResponseHeadersLength = 4;
  webRequest.UserAgent = "Mozilla/5.0 (Taco2) Gecko/20100101";
  webRequest.Credentials = CredentialCache.DefaultCredentials;

  webRequest.Method = "GET";

  using (var webResponse = webRequest.GetResponse())
  {
    using (var sr = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.UTF8))
    {
      return sr.ReadToEnd();
    }
  }
}

Codage heureux! N'hésitez pas à poser des questions dans les commentaires ci-dessous.

14
TwistedStem

Cela m'est venu à l'esprit, mais pour moi, cela était dû à un problème de protocole de sécurité.

Ajoutez simplement cette ligne

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

Plus d'informations -> https://codeshare.co.uk/blog/how-to-fix-the-error-authentication-failed-because-the-remote-party-has-closed-the-transport- stream /

0
Arun Prasad E S