我正在使用python 2.7.3构建一个SOAP客户端,并使用Canonical提供的suds 0.4.1库。服务器正在使用HTTPS进行基本身份验证。
无法在服务器上传递身份验证,甚至无法获取WSDL。我收到以下错误:
suds.transport.TransportError:HTTP错误401:未经授权
我已经尝试了suds documentation中描述的两种身份验证方法,但仍然在client = Client(url, ...)
行上面得到了上述错误。我已经确认了在Web浏览器中连接的凭据和功能,这很好。
声明wsdl_url
,username
和password
后,我尝试了:
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)
我错过了什么?
答案 0 :(得分:11)
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)
答案 1 :(得分:0)
您可以使用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
...