Excel VBA : NTLM/Kerberos & Negotiate Authentication in VBA-Web/WinHttp

标签 excel vba authentication ntlm http-negotiate

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

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

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。在一次特定调用期间,它会执行“协商”身份验证。

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

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

Microsoft 文档采用 C++JScript 语言,因此这对我也没有帮助。

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

P.S 我希望我的问题很清楚。请随时要求澄清。我找到的所有答案都会恢复为基本身份验证,但我不能这样做。我想与您分享我正在尝试连接的网站,但它位于内部网上。

最佳答案

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

这与使用 powershell script 完全相同,除了凭证缓存可能不存在。没问题,只需使用 SetAutoLogonPolicy、SetCredentials 或 SetClientCertificate (CURRENT_USER 或 LOCAL_MACHINE 是唯一有效的位置!) -- 请参阅 this -- 例如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 进行身份验证的最简单方法是在浏览器中使用开发人员工具并监视网络,您将看到所需的所有请求。

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

关于Excel VBA : NTLM/Kerberos & Negotiate Authentication in VBA-Web/WinHttp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40455494/

相关文章:

vba - 获取 Excel 工作表的实际打印区域(通过 VBA)

mysql - Microsoft Access SQL查询两个表多对一

authentication - SDDL 格式的 SID 的最大长度是多少

javascript - NestJS-错误 : Unknown authentication strategy "local"

c# - Excel 返回日期而不是计算值

vba - 如何删除隐藏的引号

excel - 保留多个字符串并删除其他数据

vba - VBA 中的作用域是否被破坏?

vba - 通过 VBA 以编程方式加密 Outlook 邮件

ruby-on-rails - 由于此警告 : [WARNING] You provided devise_for :users but there is no model User defined in your application,设计无法正常工作