git - 如何强制 Git(2.5+)HTTP 传输更喜欢 SPNEGO 而不是基本身份验证?

标签 git libcurl http-authentication spnego

总结:我正在使用 Git for Windows 2.5.1 通过 Kerbesized Git 服务器进行身份验证。当我使用 https://el2-gitlab.sa.c/kkm/GrammarTools.git 形式的 URL 时,Git 甚至不尝试协商身份验证,并询问用户名和密码。强制 Git 使用 SPNEGO 的解决方法是 provide empty username and password in the URL itself ,如 https://:@el2-gitlab.sa.c/kkm/GrammarTools.git 中所示。在这种情况下,Git 很乐意使用现有的 Kerberos 票证进行身份验证。

我可以将 Git 配置为在不调整远程 URL 的情况下尝试 SPNEGO 吗?

更多详细信息。我花了很多时间试图解决这个问题。首先我尝试了 giving an empty user name in .gitconfig ,但无济于事:

[credential "https://el2-gitlab.sa.c"]
   username = ''

当 Git 在尝试协商失败后拒绝恢复到 Basic 时,我没有遇到过关于 reverse 问题的问题,但行为是 confirmed to have changed in 2.3.1 .

用空的用户名和密码响应提示没有帮助,这与我在 SO 上找到的一些建议相反(但它们可能早于版本 2.3.1)。

最后,详细的 libcurl 输出(此处删节)表明 Git 确实尝试了基本身份验证并完全放弃了协商:

$ export GIT_CURL_VERBOSE=1
$ git clone https://el2-gitlab.sa.c/kkm/GrammarTools.git kerbtest
Cloning into 'kerbtest'...
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 401 Unauthorized
< Status: 401 Unauthorized
< Www-Authenticate: Basic realm=""
< Www-Authenticate: Negotiate
<
* Connection #0 to host el2-gitlab.sa.c left intact
Username for 'https://el2-gitlab.sa.c':

还可能有趣的是,Git 客户端在使用票证响应之前第二次重试 401 上的未经身份验证的请求:

$ git clone https://:@el2-gitlab.sa.c/kkm/GrammarTools.git kerbtest
Cloning into 'kerbtest'...
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 401 Unauthorized
< Status: 401 Unauthorized
< Www-Authenticate: Basic realm=""
< Www-Authenticate: Negotiate
* Connection #0 to host el2-gitlab.sa.c left intact
* Issue another request to this URL: 'https://:@el2-gitlab.sa.c/kkm/GrammarTools.git/info/refs?service=git-upload-pack'
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 401 Unauthorized
< Status: 401 Unauthorized
< Www-Authenticate: Basic realm=""
< Www-Authenticate: Negotiate
<
* Issue another request to this URL: 'https://:@el2-gitlab.sa.c/kkm/GrammarTools.git/info/refs?service=git-upload-pack'
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
Authorization: Negotiate YIIGtg[ .... trimmed ... ]
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 200 OK

最佳答案

git 2.8(2016 年 3 月)应该可以缓解这个问题并在 http 身份验证期间强制使用空的用户名和密码:

参见 commit 121061f (2016 年 2 月 15 日)作者 brian m. carlson (bk2204) .
(由 Junio C Hamano -- gitster -- merge 于 commit 65ba75b ,2016 年 2 月 24 日)

http: add option to try authentication without username

Performing GSS-Negotiate authentication using Kerberos does not require specifying a username or password, since that information is already included in the ticket itself.
However, libcurl refuses to perform authentication if it has not been provided with a username and password.

Add an option, http.emptyAuth, that provides libcurl with an empty username and password to make it attempt authentication anyway.

git config documentation会提到:

http.emptyAuth:

Attempt authentication without seeking a username or password.
This can be used to attempt GSS-Negotiate authentication without specifying a username in the URL, as libcurl normally requires a username for authentication.


Git 2.10.2(2016 年 10 月)将对此进行改进。

参见 commit 5275c30 (2016 年 10 月 4 日)作者:David Turner (csusbdt) .
(由 Junio C Hamano -- gitster -- merge 于 commit c6400bf ,2016 年 10 月 17 日)

http: http.emptyauth should allow empty (not just NULL) usernames

When using Kerberos authentication with newer versions of libcurl, CURLOPT_USERPWD must be set to a value, even if it is an empty value. The value is never sent to the server.
Previous versions of libcurl did not require this variable to be set.
One way that some users express the empty username/password is http://:@gitserver.example.com, which http.emptyauth was designed to support.
Another, equivalent, URL is http://@gitserver.example.com.
The latter leads to a username of zero-length, rather than a NULL username, but CURLOPT_USERPWD still needs to be set (if http.emptyauth is set).
Do so.


当服务器仅支持单一身份验证方法时,Git 2.13(2017 年第 2 季度)将减少通过 HTTP 的身份验证往返。

参见 commit 40a18fc (2017 年 2 月 25 日),和 commit 840398f (2017 年 2 月 22 日)Jeff King (peff) .
帮助:Johannes Schindelin (dscho) .
(由 Junio C Hamano -- gitster -- merge 于 commit 92718f5 ,2017 年 3 月 10 日)

http: add an "auto" mode for http.emptyauth

This variable (http.emptyauth) needs to be specified to make some types of non-basic authentication work, but ideally this would just work out of the box for everyone.

However, simply setting it to "1" by default introduces an extra round-trip for cases where it isn't useful. We end up sending a bogus empty credential that the server rejects.

The "auto" mode should make it work out of the box, without incurring any extra round-trips for people hitting Basic-only servers.

关于git - 如何强制 Git(2.5+)HTTP 传输更喜欢 SPNEGO 而不是基本身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32788405/

相关文章:

PHP 执行 ('git' )失败

git - GitLab 上的修补程序

git - 致命 : The remote end hung up unexpectedly libcurl result = 7

http - 更改基本 HTTP 身份验证领域和登录对话框消息

Git - 远程 : fatal: You are on a branch yet to be born

git - 如何使推送/拆分的子树保持最新状态?

php - curl_errno 返回 0 而不是 6

c++ - libcurl 如何更改编码 url 行为

php - laravel5.1 API 的基本 http 身份验证

android - 验证 Android 应用程序调用 Web api 服务