【问题标题】:HTTP Authentication in URL with backslash in usernameURL 中的 HTTP 身份验证,用户名中带有反斜杠
【发布时间】:2014-03-21 16:52:00
【问题描述】:

我需要 HTTP 基本身份验证才能进行 REST 调用。在用户名中,我必须提供一个域(有一个连字符),然后是一个反斜杠来将其与用户名分开,如下所示:DOM-AIN\user_name。那么密码是相当良性的。

这适用于 curl:

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

我现在需要把它放到 Python 中,但是我已经尝试了 requests 和 urllib/2/3...他们不喜欢 \ :@。即使我将 URL 编码为 %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)

还有一些其他的请求尝试,但我不再有这些了。如果有用的话,我可以得到这些错误,但如果已经知道我做错了,那就太好了......

【问题讨论】:

    标签: python curl request urllib2 urllib


    【解决方案1】:

    反斜杠应该在 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代码;它总是发送凭据而不等待带有WWW-Authenticate 标头的401 响应。

    【讨论】:

    • 我尝试了双反斜杠但它不起作用,也许它只是不被服务器接受。我会再试一次,但我还发现了另一种使用 urllib 的方法,它最接近地复制了 curl 的完成方式。我在下面提供了。
    • @NikhilHaas:上面的代码生成的Authorization 标头与curl 命令生成的标头相同。如果它不起作用,那么您的 curl 命令也会失败。
    【解决方案2】:

    首先将您的DOM-AIN\user_name 转换为base64 字符串。让我们说它的XXXXYYYYYYY。现在将此base64 字符串放入http 标头中,如下面的代码urllib2

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

    【讨论】:

      【解决方案3】:

      我找到了一种使用 urllib 的方法,this post's 提到 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 编码时,它可以工作。当我对 :@ 等其他字符进行编码时不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2017-10-29
        相关资源
        最近更新 更多