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 ...

Kenny Rullo
quelle
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.

Zambonilli
quelle
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!

Kenny Rullo
quelle
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");
Tamir
quelle
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; 
MrEyes
quelle
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;
Alexei
quelle
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;
}
Mahabubuzzaman
quelle
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
2

Die Spezifikation kann als "ISO-8859-1" oder "undefiniert" gelesen werden. Deine Entscheidung. Es ist bekannt, dass viele Server ISO-8859-1 verwenden (ob es Ihnen gefällt oder nicht) und fehlschlagen, wenn Sie etwas anderes senden.

Weitere Informationen und einen Vorschlag zur Behebung der Situation finden Sie unter http://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html

Slan
quelle
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.

Gucu112
quelle
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();
Jiten
quelle