目标:连接到 Exchange 服务器 (EWS)
方法:cURL
问题:无法获得身份验证 (NTLM),请求返回401。1
似乎有一个古老的、有据可查的2问题,它始于 cURL 从 OpenSSL 到 NSS 的迁移。我读到 NTLM 的实现依赖于 OpenSSL,因此此举破坏了 NTLM 身份验证。
问题如下所示,但重要的部分似乎是返回401
的,gss_init_sec_context()
下面是。
我不明白的是我当前的版本:
- 根据https://launchpad.net/ubuntu/+source/curl/7.22.0-3ubuntu4有一个 OpenSSL 变体
- 根据同一链接支持 NTLM
- 根据下面的日志(它说)实际上使用了这个变体(而不是 NSS
libcurl/7.22.0 OpenSSL
) - 根据以上几点,不应受到链接错误的困扰。
- 但受到影响,正如我得到 401 的事实所示
我不确定如何解决这个问题。我可以找到很多关于这个问题的旧的(主要是 2010 年的)参考,但没有新的,当然也没有解决方案。我知道提供的参考资料(参见2)表明这可能适用于旧版本 (7.19),但我不能(也不愿意)降级到该版本。
Exchange-communication (EWS) 的几种实现使用 cURL 来检索 EWS 文件(wsdl 等),所以我确信一定有一个可行的方法,但我找不到它。有谁知道我能做什么?我是否还有另一个错误,我是否错误地解释了事实,这是否仍然与链接中提供的情况相同并且永远不会修复?
1错误是这样的:
curl https://*DOMAIN*/Exchange.asmx -w %{http_code} --ntlm -u *USERNAME* --verbose --show-error
Enter host password for user '*USERNAME':
* About to connect() to DOMAIN port 443 (#0)
* Trying IP... connected
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using AES128-SHA
* Server certificate:
*SNIP*
* SSL certificate verify ok.
* Server auth using NTLM with user 'USERNAME'
> GET /EWS/Exchange.asmx HTTP/1.1
> Authorization: NTLM *snip*
> User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: DOMAIN
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Server: Microsoft-IIS/7.5
< Set-Cookie: exchangecookie=xxx; expires=Wed, 17-Jul-2013 07:45:30 GMT; path=/; HttpOnly
< WWW-Authenticate: NTLM *SNIP*
* gss_init_sec_context() failed: : Credentials cache file '/tmp/krb5cc_1005' not foundWWW-Authenticate: Negotiate
< X-Powered-By: ASP.NET
< Date: Tue, 17 Jul 2012 07:45:30 GMT
< Content-Length: 0
<
* Connection #0 to host DOMAIN left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
2例如:
- https://bugs.launchpad.net/ubuntu/+source/curl/+bug/675974
- https://bugzilla.redhat.com/show_bug.cgi?id=603783
- https://stackoverflow.com/questions/4341368/curl-always-returns-401-with-ntlm
- 这是同一个问题,但没有解决我的libcurl
NSS
中不应该出现该问题的事实。OpenSSL
- 这是同一个问题,但没有解决我的libcurl
卷曲信息:
user@server:~$ curl -V
curl 7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
我不确定为什么,但是虽然我的 7.22 版本不应该受到整个 NTLM 问题的影响,但它似乎是。
唯一的解决方案似乎是使用旧版本(<7.19,我试过 7.15)或使用新版本(我试过 7.26)。如前所述,我不能仅仅为了这个功能而降级或升级 libcurl 本身。这意味着我们需要找到解决方法......
使用的解决方法(警告:黑客即将到来)
下载并编译您要使用的 curl。我没有以 root 身份执行此操作 //
sudo
这是因为我不想替换当前的 libcurl 等!测试我们刚刚编译的新
curl
命令:它确实给出了 401,但是gss_init_sec_context()
你应该看到它变成了(最后)302 而不是 。这是成功的。hack 部分:
libcurl
调用脚本时使用它。我们正在使用第 3 方 PHP“应用程序”(我不喜欢更改所有 curl 库的原因之一),而不是直接调用它,我们制作了一个丑陋但有效的包装器,它调用了这样的东西:是的,这有缺点,是的,这是一个骨架示例(意味着您可能想添加一些东西,例如原始路径),但基础知识有点在那里。
并不是真的为此感到自豪,但我认为更多的人被这样一个事实所束缚:他们不能只是去更新他们
libcurl
的随机版本并且正在使用某种使用 eg 的插件php-ews
,或者任何基于NTLMSoapClient
.我希望还有另一种选择,但由于这是目前让它“工作”的唯一方法,我想我会分享。
对于所有 Centos /RHEL 6.X 用户,请查看:
https://bugzilla.redhat.com/show_bug.cgi?id=953864