0

当 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

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

有任何想法吗?

4

2 回答 2

0

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

回复如下,

我正在尝试使用 libcurl 连接到同时支持两者的 Web 服务器,但某些客户端无法执行 kerberos。

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

我将 CURLOPT_HTTPAUTH 设置为 CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM

a) 你使用的是什么版本的 libcurl?从输出来看,它看起来像是 7.38.0 之前的版本 - 如果是这种情况,您可能想忽略我之前的问题(包括本节),并跳转到我关于升级的评论;-) 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

将检查并更新...

于 2014-09-30T18:09:49.833 回答
0

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

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

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,客户端将提供协商凭据,并期望您可以支持它们。客户不会退回到其他方案,希望得到支持。

于 2014-09-27T02:45:02.727 回答