【问题标题】:Python SOAP client with Zeep - authentication带有 Zeep 的 Python SOAP 客户端 - 身份验证
【发布时间】:2016-10-21 09:38:40
【问题描述】:

我正在尝试使用 Zeep 来实现一个 SOAP 客户端,因为它似乎是目前唯一维护的库:

  • ZSI 看起来很不错,但它在 pypi 上的最新版本日期为 2006 年
  • suds 似乎是一个流行的替代方案,但 master 自 2011 年以来就无人维护,并且有很多分支,但似乎没有一个“官方”和“最新”足以在大型项目中使用。

因此,在尝试使用 Zeep 时,我遇到了服务器访问 WSDL 所需的身份验证。

使用 ZSI,这样的操作非常简单:

from ZSI.client import Binding
from ZSI.auth import AUTH

b = Binding(url='http://mysite.dom/services/MyWebServices?WSDL')
b.SetAuth(AUTH.httpbasic, 'userid', 'password')

我可以在 Zeep 的 __main__.py 中找到类似的东西:

from six.moves.urllib.parse import urlparse
from zeep.cache import InMemoryCache, SqliteCache
from zeep.client import Client
from zeep.transports import Transport

cache = SqliteCache() if args.cache else InMemoryCache()
transport_kwargs = {'cache': cache}
result = urlparse(args.wsdl_file)
if result.username or result.password:
    transport_kwargs['http_auth'] = (result.username, result.password)
transport = Transport(**transport_kwargs)
client = Client(args.wsdl_file, transport=transport)

但这在我的情况下不起作用,我收到一个错误:

Exception: HTTPConnectionPool(host='schemas.xmlsoap.org', port=80): Max retries exceeded with url: /soap/encoding/ (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7f3dab9d30b8>: Failed to establish a new connection: [Errno 110] Connection timed out',))

【问题讨论】:

  • 就我而言,我必须通过 _soapheaders 发送它。请查看我的answer.
  • @Pintun 您能否更改已接受的答案,因为当前答案已过时

标签: python authentication soap wsdl


【解决方案1】:

可能在较新版本的 zeep 中,较旧的解决方案不再适用。 Here is the new way:

from requests.auth import HTTPBasicAuth  # or HTTPDigestAuth, or OAuth1, etc.
from requests import Session
from zeep import Client
from zeep.transports import Transport

session = Session()
session.auth = HTTPBasicAuth(user, password)
client = Client('http://my-endpoint.com/production.svc?wsdl',
            transport=Transport(session=session))

【讨论】:

  • 是的,这个解决方案绝对可以正常工作。上述方法不适用于当前版本的 zeep。 Transport 类不接受 http_auth 参数。
【解决方案2】:

对于基本访问身份验证,您可以使用 requests 模块中的 HTTPBasicAuth 类,如 Zeep 文档 http://docs.python-zeep.org/en/master/transport.html 中所述:

from requests.auth import HTTPBasicAuth  # or HTTPDigestAuth, or OAuth1, etc.
from zeep import Client
from zeep.transports import Transport

client = Client('http://my-endpoint.com/production.svc?wsdl',
    transport=Transport(http_auth=HTTPBasicAuth(user, password)))

【讨论】:

  • 太棒了,非常感谢。我现在正在努力解决这样一个事实,即托管在 Intranet 中的 WSDL 尝试从 Internet 导入命名空间 ('schemas.xmlsoap.org/soap/encoding/"/>'),这在客户端计算机上不可用。你知道吗是否有办法阻止 zeep 客户端这样做?
  • 我不认为有一个简单的解决方法。您可以修改 WSDL 以使所有命名空间成为本地名称(例如,您可以在客户端计算机上拥有 WSDL 的副本,Zeep 可以使用它)或者以某种方式在 Intranet 上使用相应的 URL 提供模式的本地副本.
  • 我找到了一个解决方案,用本地副本覆盖传输类。参见this question.
  • 嗨,我知道你在去年 10 月写了这篇文章,但我相信现在情况已经改变了:见docs.python-zeep.org/en/master/…(基本上你需要做 session=Session() 并将传输放到会议)。但是非常感谢,如果没有你的回答,我就不会找到这个。 (我认为这是对 Requests 的更改,而不是对 Zeep 的更改)。
【解决方案3】:

在我的例子中,我使用的 API 需要 WS-Security (WSSE) 而不是 HTTP。

from zeep import Client
from zeep.wsse.username import UsernameToken

client = Client(<wsdl_url>, wsse=UsernameToken(<username>, <password>)

【讨论】:

  • 适用于 wcf 服务。
猜你喜欢
  • 1970-01-01
  • 2018-08-06
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多