HttpWebRequest przy użyciu uwierzytelniania podstawowego


139

Próbuję przejść przez żądanie uwierzytelnienia, które naśladuje „podstawowe żądanie uwierzytelniania”, do którego przyzwyczailiśmy się podczas konfigurowania usług IIS pod kątem tego zachowania.

Adres URL to: https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(ostrzeżenie: https!)

Ten serwer działa w systemie UNIX i Java jako serwer aplikacji.

Oto kod, którego używam do łączenia się z tym serwerem:

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

(Skopiowałem to z innego postu na tej stronie). Ale otrzymuję taką odpowiedź z serwera:

Połączenie bazowe zostało zamknięte: podczas wysyłania wystąpił nieoczekiwany błąd.

Wydaje mi się, że wypróbowałem wszystkie możliwe zadania, które moja wiedza na C # ma mi do zaoferowania, ale nic ...


Myślę, że ten zadziałałby, gdybyś dodał: request.UseDefaultCredentials = false;
bpeikes

Odpowiedzi:


275

Możesz również samodzielnie dodać nagłówek autoryzacji.

Po prostu nadaj nazwę „Authorization” i wartość „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);

Edytować

Zmieniono kodowanie z UTF-8 na ISO 8859-1 na Jakiego kodowania należy używać do podstawowego uwierzytelniania HTTP? i komentarz Jeroena.


3
Skąd więc masz pewność, że UTF8 to właściwe kodowanie?
Jeroen Wiert Pluimers

2
Dobry chwyt. Wygląda na to, że nagłówek żądania uwierzytelnienia powinien być zakodowany w standardzie ISO-8859-1. Per stackoverflow.com/questions/7242316/…
Zambonilli

1
Aaaargh! 1: Dzięki kolego. 2. Naprawdę chciałbym zrozumieć, dlaczego inne metody, takie jak ustawienie metody uwierzytelniania w CredentialCache, w ogóle nie działają. Powinni, prawda?
mshthn

1
Cała dokumentacja msdn wskazuje na tak, inne metody powinny działać. Jednak nigdy nie byłem w stanie zmusić ich do pracy.
Zambonilli

Nie działa dla mnie (ani utf-8 ani ISO-8859-1). Jakieś sugestie co sprawdzić? Działa, gdy robię „webRequest.Credentials = new NetworkCredential (ID użytkownika, hasło);” .
RollerCosta

56

W końcu to dostałem!

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;

a to jest 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

Jeśli możesz korzystać z tej WebClientklasy, korzystanie z uwierzytelniania podstawowego staje się proste:

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

Spróbuj tego:

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; 

Czy jest to definitywnie podstawowa autoryzacja? Czy możesz uzyskać dostęp do zasobu za pomocą swojej nazwy użytkownika / hasła za pośrednictwem przeglądarki?
MrEyes

Wydaje się, że jest to podstawowa autoryzacja przez https. Jeśli klikniesz łącze, które podałem, przeglądarka wyświetli żądanie nazwy użytkownika / hasła ”, tak samo jak w przypadku„ podstawowego uwierzytelniania ”w usługach IIS lub korzystania z pliku .htaccss w folderze za pośrednictwem apache. Próbowałem użyć programu Fiddler, ale nie mam pojęcia o.
Kenny Rullo

Właśnie dowiedziałem się, że serwis działa na serwerze HTTP IBM. To może być pomocna wiadomość?
Kenny Rullo

5

W przypadku osób korzystających z RestSharp może się to nie powieść podczas korzystania z SimpleAuthenticator (prawdopodobnie z powodu braku używania ISO-8859-1 za kulisami ). Udało mi się to zrobić, jawnie wysyłając nagłówki Basic Authentication:

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

Poniższy kod rozwiąże odpowiedź JSON, jeśli zaimplementowano uwierzytelnianie podstawowe i serwer proxy, a także rozwiązanie Problm hostingu usług IIS 7.5.

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

Nie działa dla mnie (ani utf-8, ani ISO-8859-1 ani domyślny). Jakieś sugestie, co sprawdzić? Uwaga - działa, gdy wykonam "webRequest.Credentials = new NetworkCredential (ID użytkownika, hasło);"
RollerCosta


1

Następująca konstrukcja nie działała poprawnie dla mnie:

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

CredentialCacheZamiast tego użyłem :

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

Jeśli jednak chcesz dodać wiele podstawowych danych uwierzytelniających (na przykład, jeśli istnieje przekierowanie, o którym wiesz), możesz użyć następującej funkcji, którą stworzyłem:

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

Mam nadzieję, że w przyszłości komuś to pomoże.


0

Po pierwsze, dla mnie ServicePointManager.SecurityProtocol = SecurityProtocolType. Tls12 działał zamiast Ssl3.

Po drugie, musiałem wysłać żądanie Basic Auth wraz z niektórymi danymi (zakodowane w postaci formularza). Oto pełna próbka, która po wypróbowaniu wielu rozwiązań zadziałała idealnie.

Zastrzeżenie: Poniższy kod to mieszanka rozwiązań znalezionych pod tym linkiem i kilku innych linków do przesyłania stosów, dzięki za przydatne informacje.

        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();
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.