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

时间:2015-09-25 18:22:30

标签: 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来尝试SPNEGO而无需调整远程URL?

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

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

当我遇到关于反向问题的问题时,当Git在尝试和未通过协商后拒绝恢复为Basic时,我的行为是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

3 个答案:

答案 0 :(得分:5)

git 2。8(2016年3月)应该在http身份验证期间缓解该问题并强制使用空用户名和密码

commit 121061fbrian m. carlson (bk2204)(2016年2月15日) Junio C Hamano -- gitster --于2016年2月24日commit 65ba75b合并)

  

http:添加选项以尝试不使用用户名的身份验证

     

使用Kerberos执行GSS-Negotiate身份验证不需要指定用户名或密码,因为该信息已经是   包含在机票本身中   但是,libcurl如果未提供用户名和密码,则拒绝执行身份验证。

     

添加一个选项http.emptyAuth,为libcurl提供一个空的用户名和密码,以便其尝试进行身份验证。

git config documentation会提到:

http.emptyAuth:
  

在不寻求用户名或密码的情况下尝试身份验证   这可用于尝试GSS-Negotiate身份验证,而无需在URL中指定用户名,因为libcurl通常需要用户名进行身份验证。

Git 2。10。2(Octobre 2016)将改善这一点。

commit 5275c30David Turner (csusbdt)(2016年10月4日) Junio C Hamano -- gitster --于2016年10月17日commit c6400bf合并)

  

http: http.emptyauth应该允许空(不仅仅是NULL)用户名

     

在较新版本的libcurl中使用Kerberos身份验证时,   CURLOPT_USERPWD必须设置为值,即使它是空值。   该值永远不会发送到服务器   以前版本的libcurl不需要设置此变量   某些用户表达空用户名/密码的一种方式是http://:@gitserver.example.comhttp.emptyauth旨在支持。{1}}   另一个相当的网址是http://@gitserver.example.com   后者导致用户名为零长度,而不是NULL用户名,但仍需要设置CURLOPT_USERPWD(如果设置了http.emptyauth)。
  这样做。

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

commit 40a18fc(2017年2月25日)和commit 840398f(2017年2月22日)Jeff King (peff)。 帮助:Johannes Schindelin (dscho)
Junio C Hamano -- gitster --于2017年3月10日commit 92718f5合并)

  

http:为auto

添加“http.emptyauth”模式      

需要指定此变量(http.emptyauth)以使某些类型的非基本身份验证工作,但理想情况下,这对每个人来说都是开箱即用的。

     

但是,默认情况下,将其设置为“1”会为有用的情况引入额外的往返。我们最终会发送服务器拒绝的虚假空凭证。

     

“自动”模式应该让它开箱即用,不会产生任何影响   人们打击仅限基本服务器的任何额外往返。

答案 1 :(得分:3)

这不是Git问题,而是curl问题。您患有known bug #10curl的实现远远低于Subversion中使用的libserf

关于选择auth:Git请求ANY_AUTHlibcurl,它应该选择最强大的可用机制。如果没有(使用普通curl),您就发现了一个错误。请在GitHub上向curl报告。

答案 2 :(得分:0)

注意:以前这是选定的答案,但现在已经过时,因为git v2.8。请滚动至VonC's answer,现在已选中绿色。

此行以下的所有内容都是历史性的和过时的。唐&#39;吨

在他对这个问题的回答中,大多数credit going to @Michael-O在讨论中,我认为应该为SO社区的利益发布问题的最终直接解决方案。

Michael提到的libcurl中已知错误的解决方法是创建文件~/.netrc(原始libcurl)或~/_netrc(Git for Windows 2.5+端口,基于MSys2)。该文件应为Kerberized Git服务器主机提供空的用户名和密码。由于主机匹配是精确的,因此包括短名称和完全限定的DNS名称以及可能的别名(如果有),例如,

machine gitlab.acme.com username '' password ''
machine gitlab          username '' password ''

如果一切正常,您在原始问题中看到的行记录

* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
不应再打印

,并且应使用用户的Kerberos票证进行协商验证。