HttpWebRequest mit Standardauthentifizierung


137

Ich versuche, eine Authentifizierungsanforderung zu durchlaufen, die die "grundlegende Authentifizierungsanforderung" nachahmt, die wir beim Einrichten von IIS für dieses Verhalten gewohnt sind.

Die URL lautet: https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(Warnung: https!)

Dieser Server wird unter UNIX und Java als Anwendungsserver ausgeführt.

Dies ist der Code, mit dem ich eine Verbindung zu diesem Server herstelle:

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();

(Ich habe dies von einem anderen Beitrag auf dieser Seite kopiert). Aber ich erhalte diese Antwort vom Server:

Die zugrunde liegende Verbindung wurde geschlossen: Beim Senden ist ein unerwarteter Fehler aufgetreten.

Ich glaube, ich habe jede mögliche Aufgabe ausprobiert, die mir mein Wissen über C # zu bieten hat, aber nichts ...


Ich denke, dies hätte funktioniert, wenn Sie hinzugefügt hätten: request.UseDefaultCredentials = false;
— Bpeikes

Antworten:


273

Sie können den Autorisierungsheader auch einfach selbst hinzufügen.

Geben Sie einfach den Namen "Authorization" und den Wert "Basic BASE64 ({USERNAME: PASSWORD})" ein.

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);

Bearbeiten

Die Codierung wurde von UTF-8 auf ISO 8859-1 umgestellt. Welche Codierung sollte ich für die HTTP-Basisauthentifizierung verwenden? und Jeroens Kommentar.


3
Woher wissen Sie also, dass UTF8 die richtige Codierung ist?
— Jeroen Wiert Pluimers

2
Schöner Fang. Es sieht so aus, als ob der Header der Anforderungsauthentifizierung in ISO-8859-1 codiert sein sollte. Per stackoverflow.com/questions/7242316/…
— Zambonilli

1
Aaaargh! 1: Danke, Kumpel. 2. Ich möchte wirklich verstehen, warum die anderen Methoden, die Authentifizierungsmethode im CredentialCache festlegen, überhaupt nicht funktionieren. Sie sollen, nicht wahr?
— mshthn

1
Alle msdn-Dokumentationen zeigen auf yes, die anderen Methoden sollten funktionieren. Ich habe sie jedoch nie zum Arbeiten gebracht.
— Zambonilli

Funktioniert nicht für mich (weder utf-8 noch ISO-8859-1). Irgendwelche Vorschläge, was zu überprüfen ist? Es funktioniert, wenn ich "webRequest.Credentials = new NetworkCredential (UserID, Password);" .
— RollerCosta

56

Ich habe es endlich verstanden!

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;

und das ist 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!


29

Wenn Sie die WebClientKlasse verwenden können, wird die Verwendung der Basisauthentifizierung einfach:

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");

8

Versuche dies:

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; 

Ist es definitiv eine grundlegende Authentifizierung? Können Sie auch mit Ihrem Benutzernamen / Passwort über einen Browser auf die Ressource zugreifen?
— MrEyes

Es scheint eine grundlegende Authentifizierung über https zu sein. Wenn Sie auf den von mir bereitgestellten Link klicken, zeigt der Browser die Anforderung "Benutzername / Passwort" an, genauso wie wenn Sie "Basic Auth" auf IIS ausführen oder eine .htaccss-Datei in einem Ordner über Apache verwenden. Ich habe versucht, Fiddler zu verwenden, aber Ich habe keine Ahnung.
— Kenny Rullo

Ich habe gerade erfahren, dass die Website unter IBM http Server läuft. Dies kann eine hilfreiche Nachricht sein?
— Kenny Rullo

5

Bei Verwendung von RestSharp kann dies bei Verwendung von SimpleAuthenticator fehlschlagen (möglicherweise aufgrund der Nichtverwendung von ISO-8859-1 hinter den Kulissen ). Ich habe es geschafft, indem ich explizit Basic Authentication-Header gesendet habe:

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;

3

Der folgende Code löst die JSON-Antwort, wenn die Standardauthentifizierung und der Proxy implementiert sind. Auch IIS 7.5 Hosting Problm wird aufgelöst.

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;
}

Funktioniert nicht für mich (weder utf-8 noch ISO-8859-1 noch Standard). Irgendwelche Vorschläge, was zu überprüfen ist? Bitte beachten Sie - Es funktioniert, wenn ich "webRequest.Credentials = new NetworkCredential (UserID, Password);"
— RollerCosta


1

Die folgende Konstruktion funktionierte bei mir nicht richtig:

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

Ich habe CredentialCachestattdessen verwendet:

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

Wenn Sie jedoch mehrere grundlegende Authentifizierungsdaten hinzufügen möchten (z. B. wenn Ihnen eine Umleitung bekannt ist), können Sie die folgende Funktion verwenden, die ich vorgenommen habe:

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);
    }
}

Ich hoffe, es wird in Zukunft jemandem helfen.


0

Als erstes für mich ServicePointManager.SecurityProtocol = SecurityProtocolType. Tls12 funktionierte anstelle von Ssl3.

Zweitens musste ich die Basic Auth-Anfrage zusammen mit einigen Daten (formular-urlencoded) senden. Hier ist das komplette Beispiel, das für mich perfekt funktioniert hat, nachdem ich viele Lösungen ausprobiert habe.

Haftungsausschluss: Der folgende Code ist eine Mischung aus Lösungen, die unter diesem Link und einigen anderen Stackoverflow-Links gefunden wurden. Vielen Dank für die nützlichen Informationen.

        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();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.