Excel VBA:NTLM / Kerberos 和 VBA-Web / WinHttp 中的协商身份验证

Gol*_*ion 5 authentication excel vba ntlm http-negotiate

我想与需要身份验证的网站(在 EXCEL VBA 中)的 REST API 接口,使用数字证书(.PFX文件)(NTLM 身份验证),或使用 Windows 域身份验证(Kerberos 和协商身份验证)。后者是首选,但我也不知道该怎么做,我希望有人可以分享有关如何进行这些身份验证的代码。我不能使用其他身份验证方法(例如基本),因为它不受支持。

目前我正在使用 VBA-Web ( github:VBA-tools:VBA-Web),并且我设法与 api 进行了交互,但是以一种非常奇怪的方式。我跟踪了从 Chrome 到网站的网络调用,并注意到它将 cookie 添加到每个调用的标题中。因此,在我的请求中,我补充说:

webrequest.SetHeader "Cookie", "server.com.au=35558896564.55846.54545; SDASESSION=AQISFCwMasdffczd6afASFVHfgfgsdf%2BG35FsE%3D%40AAJTSwAJSDFSDTkMw%3D%3D%23; amlbcookie=07; JSESSIONID=000f:19pcqj2d1; server2.com.au=484566584.454584.41545"
Run Code Online (Sandbox Code Playgroud)

然而,这显然很烦人,而且对用户不友好——因为每次我想使用我的 excel vba 代码时,我都必须找到 cookie。

此外,在跟踪 Chrome 中身份验证的网络调用后,我注意到它经历了各种重定向,在重定向时收集所有 cookie。在一次特定呼叫期间,它会进行"negotiate"身份验证。

VBA-Web 似乎基于 off WinHTTP,所以我环顾四周,我真的迷失在如何与WinHTTP(或 WinINet 等)交互以进行这些身份验证。我看过setCredentials方法Link,但我不确定 NTLM 或 Negotiate 的用户名和密码是什么?

或者,我尝试使用数字证书,但由于我有 PFX 文件,我不知道如何直接使用它。我已经看过Link但我不完全确定安装 PFX 后我的证书存储在哪里。我在安装过程中选择了 Personal,那么这是否意味着它在 LOCAL_MACHINE\Personal 中?更重要的是我不知道主题名称是什么。

Microsoft 文档位于C++或 中JScript,因此这对我也没有帮助。

因此,如果我能够进行身份验证并获取 cookie,那么其余的应该没问题。我将如何使用 VBA 在 Excel 中使用两种身份验证方法中的任何一种来执行此操作?

PS我希望我的问题很清楚。随时要求澄清。我找到的所有答案都恢复为基本身份验证,但我不能这样做。我会与您分享我试图与之交互的网站,但它位于内联网上。

ald*_*nte 2

您绝对可以使用 WinHttp.WinHttpRequest 从 VBA 进行 NTLM 身份验证 - 您必须添加 Microsoft WinHTTP 服务作为对 VBA 项目的引用。

它与使用powershell 脚本完全相同,只是凭证缓存可能不存在。没问题,只需使用 SetAutoLogonPolicy、SetCredentials 或SetClientCertificate(CURRENT_USER 或 LOCAL_MACHINE 是唯一有效的位置!) - 请参阅- 例如SetClientCertificate("CURRENT_USER\Personal")

Dim auth As New WinHttp.WinHttpRequest

With auth   
.Open "GET", "https://xxx.yyy", False
.setRequestHeader "Accept", "application/json" ' this is only an example, you probably don't need to set this header
.setRequestHeader <Whatever Header You Want>, <Header Value>
.SetAutoLogonPolicy(AutoLogonPolicy_Always) ' WARNING: Only use this if you trust the host you're trying to login to
.SetClientCertificate("CURRENT_USER\Personal") ' This will use the first certificate in the "CURRENT_USER\Personal" store, this might just work as is if you have a managed domain account.
.send
cookie = .getResponseHeader("Set-Cookie")
End With
Run Code Online (Sandbox Code Playgroud)

有些主机似乎会重定向您,您必须在那里进行身份验证,没问题,您只需手动(!!!)遵循重定向即可。确保禁用自动重定向。

Dim auth As New WinHttp.WinHttpRequest

With auth   
    .Open "GET", "https://xxx.yyy", False
    .setRequestHeader "Accept", "application/json" ' this is only an example, you probably don't need to set this header
    .setRequestHeader <Whatever Header You Want>, <Header Value>
    .SetAutoLogonPolicy(AutoLogonPolicy_Always) ' WARNING: Only use this if you trust the host you're trying to login to
    .SetClientCertificate("CURRENT_USER\Personal") ' This will use the first certificate in the "CURRENT_USER\Personal" store, this might just work as is if you have a managed domain account.
    .Option(WinHttpRequestOption_EnableRedirects) = False
    .send

    While .Status = "302" ' got redirected
        redirectLocation = .getResponseHeader("Location")
        ' Here you play the same game above until you get a proper session cookie
    Wend

End With
Run Code Online (Sandbox Code Playgroud)

请注意,每次重定向后,您可能希望保存获得的任何响应 cookie,因为在某些情况下后续的 http 请求必须使用该 cookie。

检查特定主机如何通过 ntlm 进行身份验证的最简单方法是在浏览器中使用开发人员工具并监视网络,您将看到所需的所有请求。

PS 在大多数情况下,使用证书不会生成 cookie,因此只需遵循相同的过程,如果您有有效的证书,则无需保存 cookie。