我尝试使用请求通过 python 访问我公司 Intranet 上的 SAS 服务,但由于身份验证失败 (401),我无法使其工作。
我正在使用 python 3.7.4,在 Windows 10 上请求 2.22.0。到目前为止,我已经尝试/检查过:
requests.get(follow_redirects=True)
HTTPBasicAuth('user', 'pass')
、HTTPDigestAuth()
、HttpNtlmAuth('user', 'pass')
requests_kerberos.HTTPKerberosAuth()
与所有可能的参数组合一起使用,包括设置 force_preemptive=True
标志和 principal=user@REALM
。我已与 klist
确认确实存在多张票证。requests_gssapi.HTTPSPNEGOAuth()
。curl -i -L -v --negotiate --user "domain\user:pswd" <protected_service_url>
,进行身份验证。www-authenticate: Negotiate
质询,使用身份验证票证进行响应。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
。但是我不知道如何改变它,因为它似乎是一个库实现细节。
如有任何帮助,我们将不胜感激。
我设法解决了这个问题。因此,对于面临类似问题的任何人,这是我的步骤:
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)
完成了!