WinHttpRequest в Inno Setup не отправляет учетные данные с заголовком Authenticate

#inno-setup #winhttprequest

#inno-setup #winhttprequest

Вопрос:

Основываясь на некотором вопросе SO, который я видел ранее, я использую WinHttpRequest внутри Inno Setup для выполнения GET запроса к веб-серверу ( localhost:8000 прямо сейчас). Минимальный приведенный ниже код, запрос направлен на встроенный сервер отладки Django ( python manage.py runserver ).

 procedure InitializeWizard();
var
    WinHttpReq: Variant;
    url: string;
    HTTPREQUEST_SETCREDENTIALS_FOR_SERVER: integer;
begin
    url := 'http://localhost:8000/odbc/test/';
    HTTPREQUEST_SETCREDENTIALS_FOR_SERVER := 0;

    WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
    WinHttpReq.Open('GET', url, false);
    WinHttpReq.SetRequestHeader('Accept','application/json');
    WinHttpReq.SetCredentials('username','password',HTTPREQUEST_SETCREDENTIALS_FOR_SERVER);
    WinHttpReq.Send();
    MsgBox(WinHttpReq.Status, mbInformation, MB_OK);
    MsgBox(WinHttpReq.ResponseText, mbInformation, MB_OK);
end;
  

Это дает мне 403, учетные данные для аутентификации не предоставлены.

Напротив, этот код в библиотеке запросов Python работает успешно.

 >> import requests
>> r = requests.get('http://localhost:8000/odbc/test/', auth=('username','password'))
>> r.status_code
200
  

Я неправильно понимаю, как работает WinHttpRequest объект? Потому что Wireshark подтверждает, что Authorization: Basic *hashstring* заголовок был отправлен в заголовке с запросами Python, но не в WinHttpRequest случае. Вероятным обходным путем было бы самостоятельно установить заголовок для WinHttpRequest объекта, но мне просто любопытно, делаю ли я что-то не так.

Суть захвата пакетов:https://gist.github.com/anonymous/597468ba76b59dae4a8d7809ee1c6feb

Скриншоты Wireshark:

WinHttpRequest в Inno Setup Захват Wireshark

Python запрашивает библиотеку Wireshark capture

Комментарии:

1. Работает для меня (на сервере Apache) — 1) Есть ли у вас какие-либо специальные символы в имени пользователя / пароле? 2) Можете ли вы попытаться перехватить HTTP-трафик, используя, например, Wireshark, как для установочного кода Inno, так и для кода Python? И опубликовать их здесь? Или, по крайней мере, журналы веб-сервера для обоих.

2. Добавлены скриншоты wireshark capture. Есть ли лучший формат для публикации записей wireshark?

3. Когда вы остановите захват, вы можете сохранить трафик в файл. Обратите внимание, что WinHttpRequest отправляет два HTTP-запроса. В первый раз без аутентификации, а затем после получения 401 он отправляет второй запрос с авторизацией. Поэтому нам нужно просмотреть оба запроса, включая ответы с сервера.

4. Добавлена суть. Я не вижу, откуда вы видите два запроса WinHttpRequest .

5. Их нет в ваших записях, потому что ваш сервер не отправляет WWW-Authenticate заголовок. Но я вижу их, когда тестирую ваш код на своем сервере (Apache). Если я настрою свой сервер так, чтобы он вел себя так же, как ваш (без WWW-Authenticate заголовка), я получаю то же поведение, что и вы (только один запрос, без Authenticate заголовка).

Ответ №1:

Я предполагаю, что это несовместимость между WinHttpRequest и вашим «сервером отладки Django».


WinHttpRequest Отправляет Authenticate заголовок только после запроса сервером с WWW-Authenticate заголовком.

В ответе 403 от вашего сервера такого заголовка нет. Следовательно, WinHttpRequest не отправляет Authorization заголовок.

Решения:

  • Заставьте ваш сервер возвращать WWW-Authenticate заголовок (и в идеале статус 401 — хотя это не требуется WinHttpRequest ).

  • Отправьте Authenticate заголовок явно с помощью:

     WinHttpReq.SetRequestHeader('Authorization', 'Basic ???');