Inno Setup 中的 WinHttpRequest 不使用 Authenticate header 发送凭据

WinHttpRequest in Inno Setup doesn't send credentials with Authenticate header

根据我之前看到的一些 SO 问题,我在 Inno Setup 中使用 WinHttpRequest 向 Web 服务器发出 GET 请求(现在 localhost:8000)。下面的最小代码,请求是 built-in 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 object 的工作原理?因为 Wireshark 确认 Authorization: Basic *hashstring* header 在 header 中与 Python 请求一起发送,但在 WinHttpRequest 情况下没有。一个可能的解决方法是为 WinHttpRequest object 自己设置 header 但我只是想知道我是否做错了什么。

抓包要点:https://gist.github.com/anonymous/597468ba76b59dae4a8d7809ee1c6feb

Wireshark 截图:

我的猜测是 WinHttpRequest 和您的 "Django debug server" 不兼容。


WinHttpRequest 发送 Authenticate header,只有在被服务器用 WWW-Authenticate header.

挑战后

您服务器的 403 响应中没有这样的 header。因此 WinHttpRequest 不会发送 Authorization header.

解决方案是:

  • 使您的服务器 return 成为 WWW-Authenticate header(最好是 401 状态 - 尽管 WinHttpRequest 不需要)。

  • 通过以下方式显式发送 Authenticate header:

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