【问题标题】:Python SOAP client, WSDL call with suds gives Transport Error 401 Unauthorized for HTTP basic authenticationPython SOAP 客户端,带有 suds 的 WSDL 调用给出传输错误 401 未经授权用于 HTTP 基本身份验证
【发布时间】:2012-07-31 14:31:42
【问题描述】:

背景

我正在使用 Python 2.7.3 构建一个 SOAP 客户端,并使用 Canonical 提供的 suds 0.4.1 库。服务器正在通过 HTTPS 使用基本身份验证。

问题

无法通过服务器上的身份验证,甚至无法访问 WSDL。我收到以下错误:

suds.transport.TransportError:HTTP 错误 401:未经授权

尝试解析和编码

我已经尝试了suds documentation 中描述的两种身份验证方法,但在client = Client(url, ...) 行中仍然出现上述错误。我已经确认了在网络浏览器中连接的凭据和能力,这一切正常。

在声明wsdl_urlusernamepassword之后,我尝试了:

client = Client(url=wsdl_url, username=username, password=password)

# as well as:

t = HttpAuthenticated(username=username, password=password)
client = Client(url=wsdl_url, transport=t)

# and even:

t = HttpAuthenticated(username=username, password=password)
t.handler = urllib2.HTTPBasicAuthHandler(t.pm)
t.urlopener = urllib2.build_opener(t.handler)
client = Client(url=wsdl_url, transport=t)

最后一个似乎,至少,从another question about HTTP authentication with suds 中的 WSDL URL 获得响应。

其他说明

这个问题与这个similar question 不同,因为我使用的是:

from suds.transport.https import HttpAuthenticated
# not:
# from suds.transport.http import HttpAuthenticated

从 Traceback 中,client = Client(url, ...) 调用显然命中了 suds.transport.https.py:

File "/usr/lib/python2.7/dist-packages/suds/client.py", line 112, in __init__ self.wsdl = reader.open(url)
File "/usr/lib/python2.7/dist-packages/suds/reader.py", line 152, in open d = self.fn(url, self.options)
File "/usr/lib/python2.7/dist-packages/suds/wsdl.py", line 136, in __init__ d = reader.open(url)
File "/usr/lib/python2.7/dist-packages/suds/reader.py", line 79, in open d = self.download(url)
File "/usr/lib/python2.7/dist-packages/suds/reader.py", line 95, in download fp = self.options.transport.open(Request(url))
File "/usr/lib/python2.7/dist-packages/suds/transport/https.py", line 60, in open return  HttpTransport.open(self, request)
File "/usr/lib/python2.7/dist-packages/suds/transport/http.py", line 64, in open raise TransportError(str(e), e.code, e.fp)

我错过了什么?

【问题讨论】:

  • +1 解释清楚的问题。我们可以看看完整的追溯吗?另外,很抱歉,如果这听起来很光顾,但您确定您使用的服务用户名和密码正确
  • @olly_uk 我添加了更多的回溯。前一行将根据我使用的client = Client(url=wsdl_url ...) 的版本而有所不同。我确信用户名和密码也一定是错误的,但我直接从配置文件复制并粘贴到浏览器中(多次!)以确保绝对确定。

标签: python soap wsdl basic-authentication suds


【解决方案1】:

suds 没有将授权标头添加到请求中,因此我手动设置了它:

import base64

# code excluded for brevity

base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
authenticationHeader = {
    "SOAPAction" : "ActionName",
    "Authorization" : "Basic %s" % base64string
}
client = Client(url=wsdl_url, headers=authenticationHeader)

【讨论】:

  • 我得到完全相同的 401:使用此方法的未经授权的问题。 :(
  • 不确定为什么选择这个作为答案。我仍然面临完全相同的 401:未经授权的错误,即使在 base64 编码之后:stackoverflow.com/questions/63545453/… 用户也提到了@SomeGuyOnAComputer
【解决方案2】:

你可以使用 SOAPpy

import SOAPpy, base64

class myHTTPTransport(SOAPpy.HTTPTransport):
    username = None
    passwd = None

    @classmethod
    def setAuthentication(cls,u,p):
        cls.username = u
        cls.passwd = p

    def call(self, addr, data, namespace, soapaction=None, encoding=None, http_proxy=None, config=SOAPpy.Config, timeout=None):

        if not isinstance(addr, SOAPpy.SOAPAddress):
          addr = SOAPpy.SOAPAddress(addr, config)

        if self.username != None:
          addr.user = self.username+":"+self.passwd

        return SOAPpy.HTTPTransport.call(self, addr, data, namespace, soapaction, encoding, http_proxy, config)


if __name__ == '__main__':

  # code for authenticating the SOAP API calls
  myHTTPTransport.setAuthentication('admin', 'admin')

  # Getting the instance of Server
  Baton = SOAPpy.WSDL.Proxy(<WSDL PATH>, transport=myHTTPTransport)

  # your code goes here
  ...

【讨论】:

    猜你喜欢
    • 2013-07-17
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多