URL中的用户名带反斜杠的HTTP身份验证

1 投票
3 回答
5689 浏览
提问于 2025-04-17 23:19

我需要在进行REST调用时使用HTTP基本认证。在用户名中,我需要提供一个带有连字符的域名,然后用反斜杠来分隔用户名,格式是:DOM-AIN\user_name。密码就比较简单了。

用curl命令可以正常工作:

curl 'https://DOM-AIN\user_name:password@myurl.com'

现在我想把这个放到Python里,但我尝试了requests和urllib/2/3...它们对\:@都不太友好。即使我把它们编码成%40等,仍然被当成实际的:,而urllib则认为我在定义一个端口,结果出现了错误:无效的套接字,我记不清了。

所以我尝试用urllib3在头部传递用户名和密码,但我收到了未授权访问的错误,我怀疑是因为我需要以某种方式对用户名进行编码,以处理反斜杠(%5C),但这似乎也不管用。

这是一些不工作的代码:

# Attempt 1
http = urllib3.PoolManager()
url1 = https://ws.....
headers = urllib3.util.make_headers(basic_auth='DOM-AIN\user_name:password')
r1 = http.request('GET', url1, headers=headers)
response = r1.data

# Attempt 2
passwordManager = urllib2.HTTPPasswordMgrWithDefaultRealm()
passwordManager.add_password(None, url, 'DOM-AIN\user_name, password)
authenticationHandler = urllib2.HTTPBasicAuthHandler(passwordManager)
opener = urllib2.build_opener(authenticationHandler)
data = opener.open(url1)

我还有其他尝试用requests的代码,但我现在没有了。如果需要的话,我可以提供这些错误信息,但如果已经知道我哪里做错了,那就太好了...

3 个回答

0

首先,把你的 DOM-AIN\user_name 转换成 base64 字符串。假设转换后的结果是 XXXXYYYYYYY。接下来,把这个 base64 字符串放到 HTTP 头部,就像下面的代码所示,使用 urllib2

headers = { 'Authorization:' : 'Basic XXXXYYYYYYY' }
req = urllib2.Request(url, data, headers)
0

我找到了一种使用urllib的方法,灵感来自于这篇帖子提到的FancyURLopener,这让我走上了正确的道路。虽然我尽量让它的工作方式接近curl,但看了Sabuj的回答后,似乎还有其他方法可以正确使用请求头,不过我还没有尝试他的办法。

import urllib
opener = urllib.FancyURLopener()
data = opener.open('https://DOM-AIN**%5C%user_name:password@url.com?whatever_parameters')
response = data.read()

当我只对反斜杠进行了URL编码时,它可以正常工作。但当我对其他字符,比如:@进行编码时,就不行了。

3

在Python的字符串中,反斜杠需要进行转义:

username = 'DOM-AIN\\user_name' # OR
username = r'DOM-AIN\user_name' # raw-string literal

举个例子:

import urllib2, base64

request = urllib2.Request('https://example.com')
credentials = base64.b64encode(username + b':' + password)
request.add_header('Authorization', b'Basic ' + credentials)
response = urllib2.urlopen(request) 

注意:和HTTPBasicAuthHandler的代码不同,它总是会发送凭证,而不需要等到收到401响应和WWW-Authenticate头。

撰写回答