我正在尝试使用WSDL和身份验证进行简单的SOAP调用,但不知道如何将凭据传递给调用。使用WSDL是否可以做到这一点,或者我是否应该以其他方式做到这一点?
from SOAPpy import WSDL
WSDLFILE = 'link/to/wsdl/file'
server = WSDL.Proxy(WSDLFILE)
result = server.methodCall()
现在,我得到这个错误:
File "/usr/lib/pymodules/python2.7/SOAPpy/Client.py", line 263, in call
raise HTTPError(code, msg)
SOAPpy.Errors.HTTPError: <HTTPError 401 Unauthorized>
这是一个相当老的问题,但由于它在google搜索"SOAPpy身份验证"时首先显示-我将留下我的发现,这样也许你不必敲你的头10个小时。回馈社会。
谷歌没有提供太多帮助,但这个示例(http://code.activestate.com/recipes/444758-how-to-add-cookiesheaders-to-soappy-calls/)让我编写自己的帮助器(版本0.0 beta)
from SOAPpy import (
WSDL,
HTTPTransport,
Config,
SOAPAddress,
)
import urllib2
import base64
class AuthenticatedTransport(HTTPTransport):
_username = None
_password = None
def call(self, addr, data, namespace, soapaction = None, encoding = None, http_proxy = None, config = Config, timeout = 10):
if not isinstance(addr, SOAPAddress):
addr = SOAPAddress(addr, config)
content_type = 'text/xml'
if encoding != None:
content_type += '; charset="%s"' % encoding
encoded_auth = None
if ( isinstance(AuthenticatedTransport._username, str) != False ):
if ( isinstance(AuthenticatedTransport._password, str) == False ):
AuthenticatedTransport._password = ""
encoded_auth = base64.b64encode('%s:%s' % (self._username, self._password))
this_request = None
if ( encoded_auth is not None ):
this_request = urllib2.Request(
url=addr.proto + "://" + addr.host + addr.path,
data=data,
headers={
"Content-Type":content_type,
"SOAPAction":"%s" % soapaction,
"Authorization":"Basic %s" % encoded_auth
}
)
else:
this_request = urllib2.Request(
url=addr.proto + "://" + addr.host + addr.path,
data=data,
headers={
"Content-Type":content_type,
"SOAPAction":"%s" % soapaction,
}
)
response = urllib2.urlopen(this_request)
data = response.read()
# get the new namespace
if namespace is None:
new_ns = None
else:
new_ns = self.getNS(namespace, data)
# return response payload
return data, new_ns
WSDL.Config.strictNamespaces = 0
username = "your_username"
password = "your_password"
WSDLFile = "https://%s:%s@some_host/your_wsdl.php?wsdl" % (username, password)
namespace = "http://futureware.biz/mantisconnect"
proxy = WSDL.Proxy(WSDLFile, namespace=namespace, transport = AuthenticatedTransport(username,password))
print(proxy.mc_get_version()) # This is my WSDL call, your will be different
无论出于何种原因,仅仅使用AuthenticatedTransport类是不够的,WSDL url本身也必须包含用户名和密码。也许这是因为这里由WSDL调用的SOAP包装器正在创建单独的HTTP会话(请记住在SOAP邮件列表中阅读它)。