HttpWebRequest utilisant l'authentification de base

139

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

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

Ce serveur fonctionne sous UNIX et Java en tant que serveur d'applications.

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 à partir d'un autre article 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 envoi.

Je pense que j'ai essayé toutes les tâches possibles que mes connaissances sur C # ont à m'offrir, mais rien ...

Kenny Rullo
la source
Je pense que celui-ci aurait fonctionné si vous aviez ajouté: request.UseDefaultCredentials = false;
vélos

Réponses:

277

Vous pouvez également simplement ajouter vous-même l'en-tête d'autorisation.

Créez simplement le nom "Authorization" et la valeur "Basic BASE64 ({USERNAME: PASSWORD})"

String username = "abc";
String password = "123";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
httpWebRequest.Headers.Add("Authorization", "Basic " + encoded);

Éditer

Passage du codage UTF-8 à ISO 8859-1 par Quel codage dois-je utiliser pour l'authentification de base HTTP? et le commentaire de Jeroen.

Zambonilli
la source
3
Alors, comment savoir avec certitude que UTF8 est le bon encodage à utiliser?
Jeroen Wiert Pluimers
2
Belle prise. Il semble que l'en-tête d'authentification de la demande doit être codé en ISO-8859-1. Par stackoverflow.com/questions/7242316/…
Zambonilli
1
Aaaargh! 1: Merci, mon pote. 2. J'aimerais vraiment comprendre pourquoi les autres méthodes, définissant la méthode d'authentification dans CredentialCache, ne fonctionneraient pas du tout. Ils sont censés le faire, n'est-ce pas?
mshthn
1
Toute la documentation msdn indique oui, les autres méthodes devraient fonctionner. Cependant, je n'ai jamais pu les faire travailler.
Zambonilli
Ne fonctionne pas pour moi (ni utf-8 ni ISO-8859-1). Des suggestions que vérifier? Cela fonctionne quand je fais "webRequest.Credentials = new NetworkCredential (UserID, Password);" .
RollerCosta
56

J'ai enfin compris!

string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
WebRequest request = WebRequest.Create(url);
request.Credentials = GetCredential();
request.PreAuthenticate = true;

et c'est GetCredential()

private CredentialCache GetCredential()
{
    string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    CredentialCache credentialCache = new CredentialCache();
    credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(ConfigurationManager.AppSettings["ead_username"], ConfigurationManager.AppSettings["ead_password"]));
    return credentialCache;
}

YAY!

Kenny Rullo
la source
29

Si vous pouvez utiliser la WebClientclasse, l'utilisation de l'authentification de base devient simple:

var client = new WebClient {Credentials = new NetworkCredential("user_name", "password")};
var response = client.DownloadString("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
Tamir
la source
8

Essaye ça:

System.Net.CredentialCache credentialCache = new System.Net.CredentialCache(); 
credentialCache.Add(
    new System.Uri("http://www.yoururl.com/"),
    "Basic", 
    new System.Net.NetworkCredential("username", "password")
);

...
...

httpWebRequest.Credentials = credentialCache; 
MrEyes
la source
Est-ce vraiment une authentification basique? De plus, pouvez-vous accéder à la ressource avec votre nom d'utilisateur / mot de passe via un navigateur?
MrEyes
Cela semble être une authentification de base sur https. Si vous cliquez sur le lien que j'ai fourni, le navigateur affiche la demande de nom d'utilisateur / mot de passe de la même manière que lorsque vous faites une "authentification de base" sur IIS ou en utilisant un fichier .htaccss sur un dossier via apache. J'ai essayé d'utiliser Fiddler mais Je n'ai aucune idée.
Kenny Rullo
je viens d'apprendre que le site Web fonctionne sous le serveur http d'IBM. Cela peut être une nouvelle utile?
Kenny Rullo
5

Pour ceux qui utilisent RestSharp , il peut échouer lors de l'utilisation de SimpleAuthenticator (probablement en raison de ne pas utiliser ISO-8859-1 en arrière-plan). J'ai réussi à le faire en envoyant explicitement des en-têtes d'authentification de base:

string username = "...";
string password = "...";

public IRestResponse GetResponse(string url, Method method = Method.GET)
{
    string encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes($"{username}:{password}"));
    var client = new RestClient(url);
    var request = new RestRequest(method );
    request.AddHeader("Authorization", $"Basic {encoded}");
    IRestResponse response = client.Execute(request);
    return response;
}

var response = GetResponse(url);
txtResult.Text = response.Content;
Alexei
la source
3

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;
}
Mahabubuzzaman
la source
Ne fonctionne pas pour moi (ni utf-8 ni ISO-8859-1 ni par défaut). Des suggestions à vérifier? Veuillez noter - Cela fonctionne quand je fais "webRequest.Credentials = new NetworkCredential (UserID, Password);"
RollerCosta
1

La construction suivante ne fonctionnait pas correctement pour moi:

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

J'ai utilisé à la CredentialCacheplace:

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

Cependant, si vous souhaitez ajouter plusieurs informations d'authentification de base (par exemple, s'il existe une redirection dont vous avez connaissance), 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.

Gucu112
la source
0

Tout d'abord, pour moi ServicePointManager.SecurityProtocol = SecurityProtocolType. Tls12 a fonctionné au lieu de Ssl3.

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

Avertissement: Le code ci-dessous est un mélange de solutions trouvées sur ce lien et d'autres liens stackoverflow, merci pour les informations utiles.

        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();
Jiten
la source