不理解为什么WinHTTP不能验证某些HTTPS资源(Not understanding why W

2019-07-17 22:04发布

我对任何形式的帮助,可以帮助我解决这个问题,万分感谢。

从Excel VBA代码,我需要下载和解析来自HTTPS网站CSV文件https://redmine.itransition.com/ 。 我尝试使用的WinHTTP来获取文件。 不过,我不明白为什么验证不起作用。 这里是一块相关的代码:

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

返回以下响应(只有特定字符串是列出):

Content-Type: text/html; charset=utf-8
Status: 406
X-Runtime: 5

不过,如果我利用成功的手动认证之后火狐发送cookie“曲奇”串

HTTPReq.setRequestHeader "Cookie", SetCookieString
HTTPReq.send

我很容易得到预期的文件。 当然,我不是很满意这样的解决方案,并要执行真正的WinHTTP的验证。 不过,我不明白什么是错的还是我在我的代码错过了什么。 最有可能我不得不使用.SetClientCertificate方法,但不清楚这个对我来说-这证书是必需的?

或者,更加一般:它WinHTTP的方法或函数应该使用调试找出哪些步骤是阻止/不正确的,让我无法正确的验证? 我待了两个星期通过MSDN和各种资源寻找,但仍然没有解决。

在此先感谢您的建议!

Answer 1:

在登录https://redmine.itransition.com/仅仅是一个HTML形式的职位,在用户名和密码的脚本/login

这是不兼容SetCredentials这是专为像基本/摘要/ NTLM基于服务器的身份验证方案。

你需要加载一个页面,没有凭据,抢什么样子的挥发性场authenticity_token生成表单及后,随着用户名和密码/login

如果它是一个基于会话的系统,它将响应与Set-cookie头+数据,需要在后续请求中使用。



Answer 2:

上述@Alex K.反应正是我一直在寻找SOOOO长! 使用Firebug和MSDN的帮助下,我完成了3个请求:

  • GET请求使用正则表达式从登录页面收集authenticity_token数据
  • POST请求来认证&收集从反应所需的Cookie串
  • GET请求最终得到我心爱的CSV

下面的一段,其正在按预期代码:

Set RegX_AuthToken = CreateObject("VBScript.RegExp")
' Below Pattern w/o double-quotes encoded: (?:input name="authenticity_token" type="hidden" value=")(.*)(?:")
RegX_AuthToken.Pattern = "(?:input name=" & Chr(34) & "authenticity_token" & Chr(34) & " type=" & Chr(34) & "hidden" & Chr(34) & " value=" & Chr(34) & ")(.*)(?:" & Chr(34) & ")"
RegX_AuthToken.IgnoreCase = True
RegX_AuthToken.Global = True

TargetURL = "https://redmine.itransition.com/login"

Set HTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")
HTTPReq.Open "GET", TargetURL, False
HTTPReq.Send

Set Token_Match = RegX_AuthToken.Execute(HTTPReq.ResponseText)
AuthToken = Token_Match.Item(0).SubMatches.Item(0)

PostData = "authenticity_token=" & AuthToken & "&back_url=https://redmine.itransition.com/" & "&username=" & UN & "&password=" & PW & "&login=Login »"

HTTPReq.Open "POST", TargetURL, False
HTTPReq.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
HTTPReq.Send (PostData)

SetCookieString = HTTPReq.GetResponseHeader("Set-Cookie")

TargetURL = "https://redmine.itransition.com/projects/pmct/time_entries.csv"
HTTPReq.Open "GET", TargetURL, False
HTTPReq.setRequestHeader "Cookie", SetCookieString
HTTPReq.Send

下面的网址是建筑POST请求帮助: http://tkang.blogspot.com/2010/09/sending-http-post-request-with-vba.html

你需要加载一个页面,没有凭据,抢什么样子生成表单和后挥发场authenticity_token,随着用户名和密码/登录。

亚历克斯K. - 在辉煌的建议,再次感谢! (:



Answer 3:

还有一件事(除上述解决方案)应该意识到在使用POST请求类似于上面的代码的情况下:对于一些模糊的原因我仍然有曾经在4-5倍(甚至更多)的痛恨406从网站,这意味着在我的情况AUTH响应是不完整的 。 后一步一步的调试小时我愉快地陷入的原因:身份验证令牌值可以具有+迹象,并从分析的几十身份验证令牌的箭头/响应代码我发现, +含令牌完全匹配406码。

该解决方案变得很明显:安全URL编码+ ES的PostData 。 的帮助下http://www.blooberry.com/indexdot/html/topics/urlencoding.htm我终于想出了以下内容:

PostData = "authenticity_token=" & Replace(AuthToken, "+", "%2B", vbTextCompare) & _
    "&back_url=https://redmine.itransition.com/projects/" & Trim(RedmineProject) & _
    "/time_entries" & "&username=" & UN & "&password=" & PW & "&login=Login »"

+ ES被取代%2B秒,这是-没有更多的406S)!

其他特殊字符不会在我的情况下无所谓,但这个教训教训。 希望这将节省几个小时的寿命了别人!



文章来源: Not understanding why WinHTTP does NOT authenticate certain HTTPS resource