Curl 使用SSPI的Kerberos身份验证

Curl 使用SSPI的Kerberos身份验证,curl,kerberos,sspi,gssapi,Curl,Kerberos,Sspi,Gssapi,注意:我设法取得了一些进展,请参见我当前问题的编辑,谢谢 我想在Windows上使用libcurl访问具有Kerberos/GSSAPI身份验证的网站。我首先尝试使用MIT Kerberos解决这个问题,但我也要求使用SSPI进行NTLM身份验证(libcurl不支持从两个不同的实现中同时使用这两种身份验证)。因此,我希望使用Windows SSPI库在Kerberos中进行身份验证。我设法用SSPI和SPNEGO支持编译libcurl 现在我的问题是,我需要使用提供的凭据连接到任何提供的领域

注意:我设法取得了一些进展,请参见我当前问题的编辑,谢谢


我想在Windows上使用libcurl访问具有Kerberos/GSSAPI身份验证的网站。我首先尝试使用MIT Kerberos解决这个问题,但我也要求使用SSPI进行NTLM身份验证(libcurl不支持从两个不同的实现中同时使用这两种身份验证)。因此,我希望使用Windows SSPI库在Kerberos中进行身份验证。我设法用SSPI和SPNEGO支持编译libcurl

现在我的问题是,我需要使用提供的凭据连接到任何提供的领域(它可能是当前用户的领域,也可能是其他用户的领域)。 据我所知,我需要从secur32.dll/security.dll调用AcquireCredentialsHandle并初始化SecurityContext来检索Kerberos票证

但每次我想让它发挥作用时,我:

  • 不要从SSPI缓存中提供的凭证/领域的DC获取任何票证(我正在使用kerbtray.exe查看条目)。
    • 在使用这些方法时,是否应该在此缓存中看到票证
  • 在使用InitializeSecurityContext/AcceptSecurityContext的客户端/服务器环回调用ImpersonateSecurityContext并查看Wireshark中的数据包后,我发现libcurl没有使用任何提供的凭据,而是回退到NTLM(这只会导致身份验证失败)
    • 环回客户端/服务器的行为是否正确(我在web上找不到任何其他实现的示例)
    • 假设模拟成功,libcurl是否应该使用线程的模拟凭据
    • libcurl是否完全支持NTLM+Kerberos和SSPI(我甚至不确定…)
  • 为了便于调试和测试,您知道有什么工具可以向SSPI缓存添加条目,比如MIT Kerberos库中的kinit吗?我正在使用Windows Server 2003资源工具包工具,但找不到任何此类工具

    任何帮助都将不胜感激


    编辑

    好的,我发现了如何使用libcurl制作我想要的东西。 最后,我假设我必须事先对SSPI做一些工作,但curl正好支持这一点

    当使用正确构建的带有SSPI和SPNEGO标志的curl版本时,curl将对kerberos领域进行身份验证,并将其存储在LSA缓存中

    使用curl.exe进行测试时,需要指定--congregate参数以及用户名/密码。但是,在使用libcurl时,只需将CURLOPT_HTTPAUTH选项设置为包含CURLAUTH_gssnegate的任何内容(例如CURLAUTH_ANY)。在我的测试中,libcurl完成了预期的Kerberos握手:

  • 联系web服务器(web.b.com,其中b.com是web服务器的kerberos领域)
  • 收到未经授权的答复,WWW Authenticate参数设置为协商
  • Libcurl/SSPI将TGS-REQ发送到当前用户域的域控制器(DC)(比如a.COM)
  • 不知何故,下一个TGS-REQ被发送到web服务器(B.COM)的域控制器
  • 收到域B.COM的Kerberos票证,并在LSA缓存中添加了一个条目(可通过klist.exe或kerbtray.exe查看)
  • Libcurl向web服务器发送带有授权信息的HTTP请求(GSS-API)
  • 然而,这是我的新问题,所有这些握手都是用当前记录的凭据进行的,比如user1@A.COM. 由于a.COM和B.COM之间存在信任关系,并且我的用户具有访问权限,因此它可以工作。我希望使用提供的凭据(user2.B.COM)登录

    此外,我不太确定是否可以在LSA缓存中添加与当前登录用户不同的条目


    通过模仿用户user2.B.COM,libcurl可以访问与该用户相关联的票证,从而向web服务器进行身份验证,我如何才能做到这一点呢?

    也许这将有助于将来的某个人,因此下面是我对上面列出的问题的解决方案

    我使用和方法模拟指定用户的线程。使用该方法,curl使用与线程的用户标识关联的LSA缓存,并使用该标识访问web服务器

    在我的设置中,我得到以下Kerberos数据包:

  • A.COM域控制器上的AS-REQ,具有KDC_ERR_error_error_REALM响应
  • B.COM域控制器上的AS-REQ,需要KRB5KDC_ERR_PREAUTH_响应
  • B.COM域控制器上的AS-REQ
  • B.COM域控制器上的TGS-REQ
  • 带有GSS-API身份验证信息的HTTP请求
  • 然后,只要模拟有效,我就可以对B.COM上的web服务器执行任何请求