无法在 SPNEGO 服务器上使用 requests-gssapi 进行身份验证

Cannot authenticate with requests-gssapi on SPNEGO server

我正在尝试使用请求通过 python 访问我公司内部网上的 SAS 服务,但由于身份验证失败 (401),我无法让它工作。

我正在使用 python 3.7.4,在 Windows 10 上请求 2.22.0。到目前为止,我有 tried/checked:

Chrome请求

[truncated]Authorization: Negotiate YIIIsgYGKwYBBQUCoIIIpjCC...
    GSS-API Generic Security Service Application Program Interface
        OID: 1.3.6.1.5.5.2 (SPNEGO - Simple Protected Negotiation)
        Simple Protected Negotiation
            negTokenInit
                mechTypes: 4 items
                mechToken: 6082086406092a864886f71201020201006e820853308208…
                krb5_blob: 6082086406092a864886f71201020201006e820853308208…
                    KRB5 OID: 1.2.840.113554.1.2.2 (KRB5 - Kerberos 5)
                    krb5_tok_id: KRB5_AP_REQ (0x0001)
                    Kerberos

=> Chrome 响应状态

HTTP/1.1 302 Found 

然后浏览器继续自动重定向到该服务。

这里是 requests_gssapi.HTTPSPNEGOAuth() 不成功的请求:

 [truncated]Authorization: Negotiate YIIHQQYJKoZIhvcSAQICAQBuggcw...
    GSS-API Generic Security Service Application Program Interface
        OID: 1.2.840.113554.1.2.2 (KRB5 - Kerberos 5)
        krb5_blob: 01006e8207303082072ca003020105a10302010ea2070305…
            krb5_tok_id: KRB5_AP_REQ (0x0001)
            Kerberos

=> 响应状态

HTTP/1.1 401 Unauthorized  (text/html)

我现在的测试代码是:

# 302 response is already handled by the first GET
r1 = session.get(url)  
    if r1.status_code != 401:
        print("Error! Server authorization failed at step 2. Expected response 401 but instead got: " + str(r1.status_code))
        return None
auth_url = r1.url
# step 2: server sends 401 and WWW-Authenticate: Negotiate header
# GSS-API (SPNEGO - Simple Protected Negotiation)
r2 = session.get(auth_url, auth=HTTPSPNEGOAuth(mutual_authentication=True))

使用 requests-gssapi 库让我最接近,但身份验证仍然失败。我不懂为什么。使用的 Kerberos 票证是相同的。我在成功的 Chrome 请求和失败的 python 请求之间看到的唯一区别是 OID。但是我不知道如何更改它,因为它似乎是一个库实现细节。

感谢任何帮助。

我设法解决了这个问题。因此,对于遇到类似问题的任何人,这是我的步骤:

  • 我用的是pythonrequests-gssapi. This is a more recent version of requests-kerberos可以原地掉落
  • 但是,这个库不适用于我的身份验证案例。原因是选择了错误的身份验证机制: OID: 1.2.840.113554.1.2.2 (KRB5 - Kerberos 5) 而不是 OID: 1.3.6.1.5.5 .2(SPNEGO - 简单保护协商)。幸运的是,已经有一个未被接受的解决方案 pull request(截至 2019 年 9 月)。将 gssapi_.py 复制到本地安装。
  • 使用拉取请求 updated README.rst 中描述的以下代码:
import gssapi
import requests
from requests_gssapi import HTTPSPNEGOAuth
try:
   spnego = gssapi,mechs.Mechanism.from_sasl_name("SPNEGO")
except AttributeError:
   spnego = gssapi.OID.from_int_seq("1.3.6.1.5.5.2")
gssapi_auth = HTTPSPNEGOAuth(mech=spnego)
r = requests.get("http://example.org", auth=gssapi_auth)

大功告成!