HttpWebRequest з використанням базової аутентифікації


139

Я намагаюся пройти запит на аутентифікацію, який імітує "основний запит на аутентифікацію", який ми звикли бачити під час налаштування IIS для такої поведінки.

URL-адреса: https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(попередження: https!)

Цей сервер працює під UNIX та Java як сервер додатків.

Це код, який я використовую для підключення до цього сервера:

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

(Я скопіював це з іншої публікації на цьому сайті). Але я отримую цю відповідь від сервера:

Основне з'єднання було закрито: при надсиланні сталася несподівана помилка.

Я думаю, що я намагався виконати всі можливі завдання, які мої знання зі C # можуть запропонувати мені, але нічого ...


Я думаю, що це спрацювало б, якби ви додали: request.UseDefaultCredentials = false;
bpeikes

Відповіді:


276

Ви також можете просто додати заголовок авторизації самостійно.

Просто введіть назву "Авторизація" та значення "Основні 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);

Редагувати

Переключив кодування з UTF-8 на ISO 8859-1 за кожне кодування потрібно використовувати для базової автентифікації HTTP? та коментар Джероена.


3
Тож як ви точно знаєте, що UTF8 - це правильне кодування для використання?
Jeroen Wiert Pluimers

2
Гарний улов. Схоже, що заголовок аутентифікації повинен бути закодований в ISO-8859-1. Per stackoverflow.com/questions/7242316 / ...
Zambonilli

1
Aaaargh! 1: Спасибі, приятелю. 2. Я дуже хотів би зрозуміти, чому інші методи, встановивши метод автентифікації в CredentialCache, взагалі не працюватимуть. Вони повинні, чи не так?
mshthn

1
Вся документація msdn вказує на так, інші методи повинні працювати. Однак мені ніколи не вдалося змусити їх працювати.
Замбоніллі

Не працює для мене (ні utf-8, ні ISO-8859-1). Будь-які пропозиції, що перевірити? Він працює, коли я роблю "webRequest.Credentials = новий NetworkCredential (UserID, Пароль);" .
RollerCosta

56

Я нарешті це отримав!

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;

і це 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;
}

ТАК!


29

Якщо ви можете використовувати WebClientклас, використання базової автентифікації стає простим:

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

Спробуйте це:

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

Здається, це є основним автором через https. Якщо ви натиснете на надане я посилання, браузер спливає запит на ім’я користувача / пароль "так само, як ви робите" основний auth "на IIS або використовуєте .htaccss файл у папці через apache. Я намагався використовувати fiddler, але у мене немає поняття про.
Кенні Рулло

Я щойно дізнався, що веб-сайт працює під сервером IBM http. Це може бути корисною новиною?
Кенні Рулло

5

Для тих, хто використовує RestSharp , він може вийти з ладу при використанні SimpleAuthenticator (можливо, через відсутність використання ISO-8859-1 поза сценою). Мені вдалося це зробити, явно надсилаючи заголовки 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

Наступний код вирішить json-відповідь, якщо існують базові аутентифікація та проксі-сервер.

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

Не працює для мене (ні utf-8, ні ISO-8859-1, ні типово). Будь-які пропозиції, що потрібно перевірити? Зверніть увагу - це працює, коли я роблю "webRequest.Credentials = новий NetworkCredential (UserID, Password);"
RollerCosta

2

Специфікацію можна прочитати як "ISO-8859-1" або "невизначено". Твій вибір. Відомо, що багато серверів використовують ISO-8859-1 (подобається він чи ні) і виходять з ладу, коли ви надсилаєте щось інше.

Докладнішу інформацію та пропозицію виправити ситуацію див. У розділі http://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html


1

Наступна конструкція для мене працювала неправильно:

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

Я використовував CredentialCacheзамість цього:

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

Однак якщо ви хочете додати кілька основних облікових даних авторизації (наприклад, якщо вам відомо про переадресацію), ви можете використовувати наступну функцію, яку я створив:

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

Сподіваюся, це допоможе комусь у майбутньому.


0

Перше, для мене ServicePointManager.SecurityProtocol = SecurityProtocolType. Tls12 працював замість Ssl3.

По-друге, мені довелося надіслати базовий запит Auth разом з деякими даними (форма-urlencoded). Ось повний зразок, який працював на мене ідеально, після спробу багатьох рішень.

Відмова: Код, наведений нижче, - це суміш рішень, знайдених на цьому посиланні та деяких інших посиланнях stackoverflow, дякую за корисну інформацію.

        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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.