HttpWebRequest с использованием обычной проверки подлинности


147

Я пытаюсь выполнить запрос аутентификации, который имитирует "базовый запрос аутентификации", который мы привыкли видеть при настройке 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;
байкеры

Ответы:


289

Вы также можете просто добавить заголовок авторизации самостоятельно.

Просто введите имя «Авторизация» и значение «Базовый BASE64 ({ИМЯ ПОЛЬЗОВАТЕЛЯ: ПАРОЛЬ})»

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
Хорошо поймал. Похоже, заголовок запроса Authentication должен быть закодирован в ISO-8859-1. За stackoverflow.com/questions/7242316/…
Замбонилли

1
Ааааа! 1: Спасибо, приятель. 2. Я действительно хотел бы понять, почему другие методы, устанавливающие метод аутентификации в CredentialCache, вообще не работают. Они должны, не так ли?
mshthn

1
Вся документация msdn указывает на то, что да, другие методы должны работать. Однако мне так и не удалось заставить их работать.
Zambonilli

У меня не работает (ни utf-8, ни ISO-8859-1). Есть предложения, что проверить? Это работает, когда я делаю «webRequest.Credentials = new NetworkCredential (UserID, Password);» .
RollerCosta

57

Наконец-то я понял!

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. Если вы нажмете на ссылку, которую я предоставил, браузер отобразит запрос имени пользователя / пароля, как и при выполнении «базовой аутентификации» в IIS или при использовании файла .htaccss в папке через apache. Я пытался использовать скрипач, но Я понятия не имею.
Кенни Рулло

Я только что узнал, что веб-сайт работает под HTTP-сервером IBM. Это может быть полезная новость?
Кенни Рулло,

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, если реализованы базовая аутентификация и прокси. Также разрешится проблема хостинга 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;
}

У меня не работает (ни utf-8, ни ISO-8859-1, ни по умолчанию). Есть предложения, что проверить? Обратите внимание - это работает, когда я делаю «webRequest.Credentials = new NetworkCredential (UserID, Password);»
RollerCosta

2

Спецификацию можно читать как «ISO-8859-1» или «undefined». Твой выбор. Известно, что многие серверы используют 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. Вместо Ssl3 работал Tls12.

Во-вторых, мне пришлось отправить запрос Basic Auth вместе с некоторыми данными (закодированными в форме). Вот полный образец, который отлично сработал для меня после многих попыток.

Отказ от ответственности: приведенный ниже код представляет собой смесь решений, найденных по этой ссылке и некоторым другим ссылкам на 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.