Ошибка аутентификации прокси-сервера HTTP 407 при вызове веб-службы - PullRequest
10 голосов
/ 25 января 2010

Я работаю над приложением .NET, которое вызывает сторонние веб-сервисы через Интернет. Службы не используют SOAP, поэтому мы вручную создаем документ запроса XML, отправляем его в службу по HTTP и получаем ответ XML.

Наш код - это служба Windows, которая запускается в контексте обычной учетной записи домена Windows и находится за прокси-сервером (Microsoft ISA Server), настроенным для проверки подлинности NTLM. У учетной записи, на которой работает наш сервис, есть разрешение на доступ к Интернету через прокси-сервер.

Код выглядит так:

// Create the request object.
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "POST";

// Configure for authenticating proxy server requiring Windows domain credentials.
request.Proxy = New WebProxy(proxyAddress) { UseDefaultCredentials = true };

// Set other required headers.
request.Accept = acceptableMimeType;
request.Headers.Add(HttpRequestHeader.AcceptCharset, acceptableCharset);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "none");
request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-gb");
request.Headers.Add(HttpRequestHeader.CacheControl, "no-store");
request.Headers.Add(HttpRequestHeader.ContentEncoding, "none");
request.Headers.Add(HttpRequestHeader.ContentLanguage, "en-gb");
request.ContentType = requestMimeType;
request.ContentLength = requestBytes.Length;

// Make the method call.
using(Stream stream = request.GetRequestStream()) {
    stream.Write(requestBytes, 0, requestBytes.Length);
}
HttpWebResponse response = (HttpWebResponse) request.GetResponse();

// Extract the data from the response without relying on the HTTP Content-Length header
// (we cannot trust all providers to set it correctly).
const int bufferSize = 1024 * 64;
List<byte> responseBytes = new List<byte>();
using(Stream stream = new BufferedStream(response.GetResponseStream(), bufferSize)) {
    int value;
    while((value = stream.ReadByte()) != -1) {
        responseBytes.Add((byte) value);
    }
}

Это прекрасно работает, если прокси-сервер выключен или URL-адрес занесен в белый список как не требующий аутентификации, но как только аутентификация активна, он всегда завершается ошибкой HTTP 407.

Я поместил приведенный выше код в тестовый комплект и попробовал все возможные способы настройки свойства request.Proxy, но безуспешно.

Затем я заметил, что все сторонние веб-сервисы, которые мы должны вызывать, являются HTTPS. Когда я попытался получить доступ к ним по HTTP, прокси-аутентификация начала работать. Есть ли какой-то дополнительный обруч, через который я должен прыгнуть, чтобы получить аутентификацию прокси и HTTPS, чтобы играть хорошо?

PS: те же проблемы возникают с прокси-сервером SmoothWall с открытым исходным кодом, поэтому я не могу просто списать его как ошибку в ISA Server.

PPS: я знаю, что вы можете настроить параметры прокси в app.config, но (а) выполнение этого в коде не должно иметь никакого значения, и (б) дизайн приложения требует, чтобы мы прочитали настройки прокси из база данных во время выполнения.

Ответы [ 4 ]

12 голосов
/ 25 января 2010

Вы пробовали установить прокси в app.config?

Чтобы отключить прокси, в файле App.config добавьте следующую конфигурацию

<system.net>
  <defaultProxy enabled="false" useDefaultCredentials="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

Чтобы включить прокси-сервер и использовать параметры прокси-сервера по умолчанию (указанные в IE), добавьте эту конфигурацию в файл App.config

<system.net>
  <defaultProxy enabled="true" useDefaultCredentials="true">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>
3 голосов
/ 02 октября 2010

У меня была похожая ситуация

Вы заметили, что это работало, когда вы заходили в интернет, прежде чем запустили код? и если вы не пользовались Интернетом целую вечность (20 минут для меня), вы получили ошибку.

Вы пытались установить учетные данные прокси напрямую?

//setup the proxy
request.Proxy = new WebProxy("proxyIp", 8080);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;

Надеюсь, это тоже исправит вашу проблему

1 голос
/ 27 сентября 2010

Думаю, мне придется списать этот вопрос. Мой оригинальный опубликованный код иногда работает. Наш прокси-сервер крайне ненадежен; в одну минуту он заблокирует подключение к Интернету из любого программного обеспечения, а в следующую разрешит. Похоже, что ИТ-специалисты бессильны что-либо с этим поделать, и мы (все, кроме ИТ-отдела) не имеем полномочий вносить изменения в сетевую инфраструктуру.

Если у кого-нибудь есть идеи о том, как «укрепить» мой код, чтобы компенсировать ненадежный прокси-сервер, мне было бы интересно их услышать. : -)

0 голосов
/ 25 января 2010

Что-то не так с сертификатом вашего прокси-сервера? Если ваш сервис не может установить HTTPS, он выдаст ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...