【问题标题】:libcurl negotiate fallback to ntlmlibcurl 协商回退到 ntlm
【发布时间】:2014-09-26 16:29:31
【问题描述】:

当 kerberos 不可用时,我希望 libcurl 回退到 NTLM。

我正在使用这个设置,

// explicit
curl_easy_setopt(_curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM | CURLAUTH_GSSNEGOTIATE);
// or any
curl_easy_setopt(_curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); 

实际发生的是服务器发送支持的方案

<= recv header: HTTP/1.1 401 Unauthorized
<= recv header: Content-Length: 0
text: Server Microsoft-HTTPAPI/2.0 is not blacklisted
<= recv header: Server: Microsoft-HTTPAPI/2.0
<= recv header: WWW-Authenticate: Negotiate
<= recv header: WWW-Authenticate: NTLM

但客户端只发送一个协商令牌

text: Server auth using GSS-Negotiate with user ''
=> send header: POST /daas/services/hello HTTP/1.1
Authorization: Negotiate YHkGBisGAQUFAqBvMG2gMDAuBgorBgEEAYI3AgIKBgkqhkiC9xI...TC1NT0JMR0VS
User-Agent: libcurl-agent/1.0
Host: localhost:8008
Accept: */*
Content-Length: 328
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------19e8c490d70b39c1
....

由于我还没有定义 SPN,我希望 NTLM 回退可以工作,但我明白了

<= recv header: HTTP/1.1 401 Unauthorized
<= recv header: Content-Length: 0
text: Server Microsoft-HTTPAPI/2.0 is not blacklisted
<= recv header: Server: Microsoft-HTTPAPI/2.0
text: Authentication problem. Ignoring this.
<= recv header: WWW-Authenticate: Negotiate oYIBHDCCAAAAPRwBFAFIAAgAEA.....BvAG0ABQAcAGMAb
<= recv header: Date: Fri, 26 Sep 2014 16:16:24 GMT
text: HTTP error before end of send, stop sending
<= recv header:
text: Closing connection 2

我认为客户端应该发送几个可能的令牌并让服务器选择要回答的。

有什么想法吗?

【问题讨论】:

    标签: c++ curl libcurl ntlm negotiate


    【解决方案1】:

    没有;客户端应该发送最佳机制,它不应该发送所有机制。

    这些机制不是“后备”,因为如果一种机制失败,它将尝试第二种,然后是第三种,等等。对于服务器宣传它支持协商的情况,这将是一个错误的优化,但在事实并非如此。这将演变为:

    Server: Hi, I suppose Negotiate, NTLM, Digest and Basic
    Client: Okay, here's some Negotiate credentials
    Server: Sorry! Either your credentials do not authenticate you, or whomever you authenticated as does not have authorization to view this page.
    Client: Okay, well, what if I give you the same credentials, only in NTLM form
    Server: What difference does that make?  You still can't come in.
    Client: What about Digest?
    Server: What do you mean, digest?  What makes you think that if I rejected your Negotiate and your NTLM credentials that suddenly your digest credentials will be any different?
    Client: Well, here's the same credentials with Basic
    Server: Okay, seriously, just go away.
    

    简单地说,您的服务器配置不正确:如果您宣传 Negotiate,客户端将提供协商凭据,并期望您可以支持它们。客户将不会退回到其他方案,希望这些方案会得到支持。

    【讨论】:

    • 同意;这也符合我的经验,但任何没有能力的客户应该直接转到 NTLM。我看到一些客户端配置错误,他们认为可以执行 krb5 但不能(例如时间偏差)。
    • 不是重点,服务器端支持这两种身份验证方法,SPN 可用于完整的主机名,但使用 IP 或没有 SPN 的别名会导致失败。虽然如果我要求 curl 只使用 NTLM 它工作正常。如果不将它们用作后备,那么位掩码身份验证方法有什么意义?
    • 如果您没有 SPN,则您与 Kerberos 服务器没有信任关系。这与 IP 地址或名称解析无关。您缺少证书并且无法执行 Kerberos。 “我说我可以执行协商,但实际上我做不到。”
    • 嗯...实际情况是我有一个 SPN "HTTP/hostname.tree.domain.com" 并且客户端在同一个域中向 "hostname" 发送消息,名称解析成功并建立了连接,但客户端构造的 SPN 与服务器端的任何 SPN 都不匹配。
    • 另外,请参阅这篇文章 - stackoverflow.com/questions/12260587/…
    【解决方案2】:

    我实际上已经去注册了 libcurl 邮件列表并且很快就得到了答复,

    回复如下,

    我正在尝试使用 libcurl 连接到支持 两者都有,但有些客户端不能做 kerberos。

    当您说某些客户端无法使用 Kerberos 时,您的意思是什么?您有什么限制阻止使用 Kerberos?这是否意味着 libcurl 不能或不应该使用 Kerberos 的限制?

    我将 CURLOPT_HTTPAUTH 设置为 CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM

    a) 你使用的是什么版本的 libcurl?从输出来看,它看起来像是 7.38.0 之前的版本 - 如果是这种情况,您可能想忽略我之前的问题(包括本节),并跳转到我关于升级的 cmets ;-) b) 您使用的是什么平台? Windows、Linux 等... c) 如果您使用的是 Windows,您是使用针对 Windows SSPI 编译的 libcurl 版本还是使用 GSS-API 库(例如 MIT Kerberos 或 Heimdal)编译的版本?

    libcurl 是否应该回退到 NTLM?

    没有……

    不幸的是,我不是我们的 HTTP 专家之一,所以我在这里可能是错的,但我会尝试用我的 curl 身份验证帽和一些有限的 HTTP 知识来回答这个问题 ;-)

    我的理解是,协商 (SPNEGO) 身份验证机制将尝试执行 Kerberos,然后在 Kerberos 失败时回退到 NTLM 作为其与服务器通信的一部分。因此,您只会看到分别来自客户端和服务器的“WWW-Authorization: Negotiate”和“WWW-Authenticate: Negotiate”标头,而不是前面的“WWW-Authorization: NTLM”和“WWW-Authenticate: NTLM”的组合”。

    因此,libcurl 本身不需要回退,因为 SPNEGO 通信将为我们处理它;-)

    我做错了什么吗?

    我们在 7.38.0 中修复了一些与协商相关的问题,主要问题是:

    • 使用 GSS-API 库编译时,我们没有使用正确的 SPNEGO OID
    • 如果 Kerberos 失败,则不会回退到 NTLM
    • 弃用 CURLAUTH_GSSNEGOTIATE 并引入 CURLAUTH_NEGOTIATE

    因此,我会推荐你​​:

    • 升级到 7.38.0
    • 使用 CURLAUTH_NEGOTIATE 代替 CURLAUTH_GSSNEGOTIATE |CURLAUTH_NTLM

    将检查并更新...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 1970-01-01
      • 2021-11-01
      • 2020-03-29
      相关资源
      最近更新 更多