Python SOAP client, вызов WSDL с suds дает транспортную ошибку 401 Unauthorized для базовой аутентификации HTTP
фон
Я создаю SOAP-клиент с python 2.7.3 и использую библиотеку suds 0.4.1, предоставленную Canonical. Сервер использует обычную проверку подлинности по протоколу HTTPS.
не может пройти аутентификацию на сервере, даже чтобы добраться до WSDL. Я получаю следующую ошибку:
Югов.транспорт.TransportError: ошибка HTTP 401: неавторизованный
попытки разрешения и код
я пробовал оба метода аутентификации, описанной в suds документация, но все равно получите ошибку выше в client = Client(url, ...)
линии. Я подтвердил учетные данные и возможность подключения в веб-браузере, который отлично работает.
после объявления 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)
кажется, что последний, по крайней мере, получает ответ от URL-адреса WSDL в еще один вопрос об аутентификации HTTP с пеной.
другие Примечания
этот вопрос отличается от этого аналогичный вопрос потому что я использую:
from suds.transport.https import HttpAuthenticated
# not:
# from suds.transport.http import HttpAuthenticated
и с обратной стороны,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)
что я упустил?
2 ответов
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)
вы можете использовать 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
...