使用 QNetworkAccessManager 通过 HTTPS 下载文件:如何进行身份验证?

Posted

技术标签:

【中文标题】使用 QNetworkAccessManager 通过 HTTPS 下载文件:如何进行身份验证?【英文标题】:Downloading file via HTTPS using QNetworkAccessManager: How to authenticate? 【发布时间】:2014-07-14 15:15:09 【问题描述】:

您可以在任何地方找到的一般答案是使用 Signal authenticationRequired(QNetworkReply*, QAuthenticator*),然后将登录凭据填充到给定的 QAuthenticator 对象中。

但是,这在我的情况下不起作用,因为该信号永远不会发出。原因:服务器没有返回授权失败,而是将我重定向到登录页面。所以我的程序只会下载那个页面。

我发现了如何通过检查 QNetworkReply 的属性 QNetworkRequest::RedirectionTargetAttribute 来捕捉它。 所以我可以检测到重定向并向用户询问身份验证信息。

但是...我从那里去哪里?如何设置认证数据?我可以手动将 QAuthenticator 设置为我的 QNetworkRequest 或我的 QNetworkAccessManager 吗?我没有找到任何方法来做到这一点,只是通过上面提到的信号/槽机制,它不起作用,因为它不会触发。

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

来自文档,

http://qt-project.org/doc/qt-5/qauthenticator.html

QAuthenticator 支持以下认证方式:

基本 NTLM 版本 2 摘要-MD5

由于您被重定向到登录页面,并且您没有说明上述任何身份验证方法是否有效,我会假设它不起作用,因为发送了基本身份验证之类的内容对服务器的每个请求。登录页面通常对客户端进行身份验证,并使用某种 cookie 进行将来的身份验证。为此,

    检测登录页面 将正确的凭据传递给服务器(根据表单的需要) 在登录页面的 QNetworkReply 中,查找 cookie(Set-Cookie 标头)。 将相关 cookie 与您的请求一起传回。 如果有效,您将不再被重定向到登录页面。

有关 cookie 的信息,您可以通过 Wikipedia 获得概述,但对于实施,您需要查看 RFC 6265,

如果这不正确,并且您可以使用基本身份验证,则该信息将在 URL 本身中传递。在您的 QUrl 中设置用户名和密码,如果有效,您将不会被重定向。 http://qt-project.org/doc/qt-5/qurl.html#setPassword

【讨论】:

感谢您的回复。我想我可以为 one 服务器和登录表单构建您建议的东西(“2. 根据表单的需要将适当的凭据传递给服务器”)。但这并不是一个真正令人满意的解决方案,因为我希望它可以与任何 https 连接通用。至于身份验证方法:我尝试只使用 url 传递基本身份验证,但这是行不通的。至于 NTLM 2 和 Digest-MD5,我什至不知道......我无法尝试,因为我无法将我的身份验证信息传递给服务器。 好的,我最终几乎按照你的建议做了,除了没有使用所需的登录凭据对服务器进行 POST - 这很难做到,因为 POST必须专门针对登录页面的需求进行定制——我使用 QWebView(附有我的 QNetworkAccessManager)来显示登录页面本身。用户必须登录,然后我可以从 Access Manager 的 QNetworkCookieJar 中获取 cookie 并将其传递给新的下载请求。它应该适用于几乎任何页面,因为我使用的是原始登录机制。再次感谢您的帮助!

以上是关于使用 QNetworkAccessManager 通过 HTTPS 下载文件:如何进行身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

离线使用 QNetworkAccessManager

跨 dll 使用 QNetworkAccessManager

使用 QNetWorkAccessManager 将值传递给插槽

如何使用 Qt/QNetworkAccessManager (C++) 实现 SFTP

如何使用 QNetworkAccessManager 找出数据传输延迟

使用 QNetworkAccessManager 时如何处理代理