无法在 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:
requests.get(follow_redirects=True)
- 使用
HTTPBasicAuth('user', 'pass')
、HTTPDigestAuth()
、HttpNtlmAuth('user', 'pass')
- 对所有可能的参数组合使用
requests_kerberos.HTTPKerberosAuth()
,包括设置 force_preemptive=True
标志和 principal=user@REALM
。我已与 klist
确认确实存在多张票。
- 正在安装 MIT Kerberos 并使用
requests_gssapi.HTTPSPNEGOAuth()
。
- 在 git bash 中使用 curl 命令
curl -i -L -v --negotiate --user "domain\user:pswd" <protected_service_url>
进行身份验证。
- 在 Internet explorer/Chrome 中打开 url 显然有效。我不必在任何地方输入我的凭据,任何身份验证都在后台处理。
- 包的交换遵循基本的 Kerberos 身份验证流程:请求受保护的服务,接收到身份验证服务的重定向,跟随没有身份验证的重定向,获得 401 响应和
www-authenticate: Negotiate
质询,响应身份验证票。
- 我已经检查了与 Wireshark 的包交换。下面是来自Chrome(成功)的HTTP包的关键请求+响应认证部分:
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)
大功告成!
我正在尝试使用请求通过 python 访问我公司内部网上的 SAS 服务,但由于身份验证失败 (401),我无法让它工作。
我正在使用 python 3.7.4,在 Windows 10 上请求 2.22.0。到目前为止,我有 tried/checked:
requests.get(follow_redirects=True)
- 使用
HTTPBasicAuth('user', 'pass')
、HTTPDigestAuth()
、HttpNtlmAuth('user', 'pass')
- 对所有可能的参数组合使用
requests_kerberos.HTTPKerberosAuth()
,包括设置force_preemptive=True
标志和principal=user@REALM
。我已与klist
确认确实存在多张票。 - 正在安装 MIT Kerberos 并使用
requests_gssapi.HTTPSPNEGOAuth()
。 - 在 git bash 中使用 curl 命令
curl -i -L -v --negotiate --user "domain\user:pswd" <protected_service_url>
进行身份验证。 - 在 Internet explorer/Chrome 中打开 url 显然有效。我不必在任何地方输入我的凭据,任何身份验证都在后台处理。
- 包的交换遵循基本的 Kerberos 身份验证流程:请求受保护的服务,接收到身份验证服务的重定向,跟随没有身份验证的重定向,获得 401 响应和
www-authenticate: Negotiate
质询,响应身份验证票。 - 我已经检查了与 Wireshark 的包交换。下面是来自Chrome(成功)的HTTP包的关键请求+响应认证部分:
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)
大功告成!