5

我想与需要身份验证的网站(在 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"

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

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

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

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

Microsoft 文档在C++或中JScript,所以这对我也没有帮助。

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

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

4

2 回答 2

1

您绝对可以使用 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

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

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

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

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

PS 在大多数情况下,使用证书不会生成 cookie,因此只需按照相同的步骤进行操作,如果您拥有有效证书,则无需保存 cookie。

于 2020-10-22T08:41:24.837 回答
0

你能检查一下这个是否适合你吗?

我不能确定 VBA,但从 VBA 启动 PowerShell 似乎是一种不需要太多努力的解决方法。

如何使用 VBA 或 Powershell 将具有 NTLM 身份验证的 Sharepoint 服务器中的列表导出到 Excel

于 2019-02-04T03:37:02.390 回答