173 votes

HttpWebRequest avec authentification de base

J'essaie de passer par une demande d'authentification qui imite la "demande d'authentification de base" que nous avons l'habitude de voir lorsque nous configurons IIS pour ce comportement.

L'URL est le suivant : https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(avertissement : https !)

Ce serveur fonctionne sous UNIX et Java comme serveur d'application.

Voici le code que j'utilise pour me connecter à ce serveur :

CookieContainer myContainer = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
request.Credentials = new NetworkCredential(xxx,xxx);
request.CookieContainer = myContainer;
request.PreAuthenticate = true;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

(J'ai copié ceci d'un autre post sur ce site). Mais je reçois cette réponse du serveur :

La connexion sous-jacente a été fermée : Une erreur inattendue s'est produite lors d'un un envoi.

Je pense avoir essayé toutes les tâches possibles que mes connaissances en C# peuvent m'offrir, mais rien...

6voto

Jiten Points 137

Première chose, pour moi ServicePointManager.SecurityProtocol = SecurityProtocolType. Tls12 a fonctionné à la place de Ssl3.

Deuxièmement, j'ai dû envoyer la requête Basic Auth avec quelques données (form-urlencoded). Voici l'exemple complet qui a parfaitement fonctionné pour moi, après avoir essayé de nombreuses solutions.

Disclaimer : Le code ci-dessous est un mélange de solutions trouvées sur ce lien et d'autres liens de stackoverflow, merci pour l'information utile.

        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        String username = "user_name";
        String password = "password";
        String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));

        //Form Data
        var formData = "var1=val1&var2=val2";
        var encodedFormData = Encoding.ASCII.GetBytes(formData);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("THE_URL");
        request.ContentType = "application/x-www-form-urlencoded";
        request.Method = "POST";
        request.ContentLength = encodedFormData.Length;
        request.Headers.Add("Authorization", "Basic " + encoded);
        request.PreAuthenticate = true;

        using (var stream = request.GetRequestStream())
        {
            stream.Write(encodedFormData, 0, encodedFormData.Length);
        }

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

4voto

Mahabubuzzaman Points 319

Le code suivant résoudra la réponse json si l'authentification de base et le proxy sont implémentés. Le problème d'hébergement IIS 7.5 sera également résolu.

public string HttpGetByWebRequ(string uri, string username, string password)
{
//For Basic Authentication
    string authInfo = username + ":" + password;
    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));

//For Proxy
    WebProxy proxy = new WebProxy("http://10.127.0.1:8080", true);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = "GET";
    request.Accept = "application/json; charset=utf-8";
    request.Proxy = proxy;

    request.Headers["Authorization"] = "Basic " + authInfo;

    var response = (HttpWebResponse)request.GetResponse();

    string strResponse = "";
    using (var sr = new StreamReader(response.GetResponseStream()))
    {
        strResponse= sr.ReadToEnd();

    }

    return strResponse;
}

2voto

Slan Points 372

La spécification peut être lue comme "ISO-8859-1" ou "undefined". C'est à vous de choisir. On sait que de nombreux serveurs utilisent ISO-8859-1 (qu'on le veuille ou non) et qu'ils échoueront si vous envoyez quelque chose d'autre.

Pour plus d'informations et une proposition pour remédier à la situation, voir http://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html

1voto

Gucu112 Points 322

La construction suivante ne fonctionnait pas correctement pour moi :

request.Credentials = new NetworkCredential("user", "pass");

J'ai utilisé CredentialCache au lieu de cela :

CredentialCache credentialCache = new CredentialCache
{
    {
        new Uri($"http://{request.Host}/"), "Basic",
        new NetworkCredential("user", "pass")
    }
};
request.Credentials = credentialCache;

Cependant, si vous souhaitez ajouter plusieurs identifiants de base (par exemple s'il y a une redirection que vous connaissez), vous pouvez utiliser la fonction suivante que j'ai créée :

private void SetNetworkCredential(Uri uriPrefix, string authType, NetworkCredential credential)
{
    if (request.Credentials == null)
    {
        request.Credentials = new CredentialCache();
    }

    if (request.Credentials.GetCredential(uriPrefix, authType) == null)
    {
        (request.Credentials as CredentialCache).Add(uriPrefix, authType, credential);
    }
}

J'espère que cela aidera quelqu'un à l'avenir.

0voto

Rick Drayson Points 11

L'une des raisons pour lesquelles la première réponse et d'autres ne vous conviennent pas est qu'il manque une ligne critique. (Notez que de nombreux manuels de l'API ne tiennent pas compte de cette nécessité).

request.PreAuthenticate = true;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X