winhttp 访问https_不理解为什么WinHTTP不能验证某些HTTPS资源

I'd be extremely grateful for any kind of help that may help me resolving the problem.

From Excel VBA code I need to download & parse CSV file from HTTPS site https://redmine.itransition.com/. I try to use WinHTTP to get the file. However, I can't understand why authentication does not work. Here is the piece of related code:

TargetURL = "https://redmine.itransition.com/projects/pmct/time_entries.csv"

Set HTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")

HTTPReq.Option(4) = 13056 ' WinHttpRequestOption_SslErrorIgnoreFlags 13056: ignore all err, 0: accept no err

HTTPReq.Open "GET", TargetURL, False

HTTPReq.SetCredentials "UN", "PW", 0

HTTPReq.send

returns the following response (only certain strings are listed):

Content-Type: text/html; charset=utf-8

Status: 406

X-Runtime: 5

However, if I send "Cookie" string from Firefox cookie after successful manual authentication using

HTTPReq.setRequestHeader "Cookie", SetCookieString

HTTPReq.send

I easily get the expected file. Of course I'm not happy with such solution, and want to perform true WinHTTP authentication. However, I can't understand what's wrong or what I miss in my code. Most likely I have to use .SetClientCertificate method, but this is unclear for me - which cert is required?

Or, being more general: which WinHTTP methods or functions I should use for debugging to find out which step is blocking / incorrect and prevents me from correct authentication? I spent 2 weeks seeking through MSDN and various resources, but still have no solution.

Thanks in advance for your suggestions!

解决方案

The logon at https://redmine.itransition.com/ is just an HTML form that posts a username & password to a script at /login.

This is not compatible with SetCredentials which is designed for server based authentication schemes like basic/digest/ntlm.

You need to load that page with no credentials, grab what looks like the volatile field authenticity_token from the generated form & post that along with username & password to /login.

If its a session based system it will response with the set-cookie header + data you need to use in subsequent request.

以下是使用 WinHTTP 在 Qt 中进行 HTTPS 请求的示例代码: ```cpp #include <QCoreApplication> #include <QUrl> #include <QDebug> #include <QByteArray> #include <Windows.h> #include <winhttp.h> #pragma comment(lib,"winhttp.lib") int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建 WinHTTP 会话 HINTERNET hSession = WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_SECURE); if (!hSession) { qDebug() << "WinHttpOpen failed: " << GetLastError(); return -1; } // 创建 HTTP 连接 QUrl url("https://www.example.com"); HINTERNET hConnect = WinHttpConnect(hSession, reinterpret_cast<const wchar_t*>(url.host().utf16()), url.port() == -1 ? INTERNET_DEFAULT_HTTPS_PORT : url.port(), 0); if (!hConnect) { WinHttpCloseHandle(hSession); qDebug() << "WinHttpConnect failed: " << GetLastError(); return -1; } // 创建 HTTP 请求 HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", reinterpret_cast<const wchar_t*>(url.path().utf16()), L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); if (!hRequest) { WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); qDebug() << "WinHttpOpenRequest failed: " << GetLastError(); return -1; } // 发送 HTTP 请求 if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) { WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); qDebug() << "WinHttpSendRequest failed: " << GetLastError(); return -1; } // 等待响应 if (!WinHttpReceiveResponse(hRequest, 0)) { WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); qDebug() << "WinHttpReceiveResponse failed: " << GetLastError(); return -1; } // 读取响应数据 QByteArray responseData; DWORD dwSize = 0; do { char szData[1024] = { 0 }; if (!WinHttpReadData(hRequest, szData, sizeof(szData) - 1, &dwSize)) { WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); qDebug() << "WinHttpReadData failed: " << GetLastError(); return -1; } responseData.append(szData, static_cast<int>(dwSize)); } while (dwSize > 0); // 输出响应数据 qDebug() << responseData; // 关闭 WinHTTP 相关句柄 WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return a.exec(); } ``` 在这个示例中,我们增加了一个 `WINHTTP_FLAG_SECURE` 标志来打开安全连接。请注意,在使用 HTTPS 请求时,我们需要确保我们使用的证书是受信任的,否则 WinHTTP 将无法建立安全连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值