python - 带有时间戳标记的 UsernameToken || python || WS-安全性 (WSSE)

标签 python soap ws-security zeep wsse

我应该使用 python 重新创建有效负载的这一部分。

<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
     <wsu:Timestamp wsu:Id="TS-C85E4BAAC54A3C164416475054038092">
        <wsu:Created>2022-03-17T08:23:23.809Z</wsu:Created>
        <wsu:Expires>2022-03-17T08:24:23.809Z</wsu:Expires>
     </wsu:Timestamp>
     <wsse:UsernameToken wsu:Id="UsernameToken-C85E4BAAC54A3C164416475053981971">
        <wsse:Username>XXXXXXXXXXXXXXX</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXXXXXXXXXXXXXXXXXXXXXX</wsse:Password>
        <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">zL/iJlH2YPm83y+t0wd3Dw==</wsse:Nonce>
        <wsu:Created>2022-03-17T08:23:18.195Z</wsu:Created>
     </wsse:UsernameToken>
  </wsse:Security>

经过一番研究,我发现有一个名为“zeep”的库可以处理这个问题,唯一的问题是,据我所知,关于它的文档很少。

带有时间戳 token 的 UsernameToken

要将 UsernameToken 与 Timestamp token 一起使用,首先需要一个 WSU.Timestamp() 实例,然后使用包含 WSU.Created() 和 WSU.Expired() 元素的列表扩展它,最后将其作为 timestamp_token 传递UsernameToken() 的关键字参数。

>>> import datetime
>>> from zeep import Client
>>> from zeep.wsse.username import UsernameToken
>>> from zeep.wsse.utils import WSU
>>> timestamp_token = WSU.Timestamp()
>>> today_datetime = datetime.datetime.today()
>>> expires_datetime = today_datetime + datetime.timedelta(minutes=10)
>>> timestamp_elements = [
...         WSU.Created(today_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")),
...         WSU.Expires(expires_datetime.strftime("%Y-%m-%dT%H:%M:%SZ"))
...]
>>> timestamp_token.extend(timestamp_elements)
>>> user_name_token = UsernameToken('username', 'password', timestamp_token=timestamp_token)
>>> client = Client(
...     'http://www.webservicex.net/ConvertSpeed.asmx?WSDL', wsse=user_name_token
...)

输出

<Element {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp at 0x7f46e09032c0>
2022-03-17 09:38:20.627353
2022-03-17 09:48:20.627353
[<Element {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Created at 0x7f46e0903400>, <Element {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Expires at 0x7f46e0916f40>]
None
<zeep.wsse.username.UsernameToken object at 0x7f46e0911fa0>
<zeep.client.Client object at 0x7f46e0911f40>

这就是关于我的案例的全部内容,有谁知道我如何构建这段代码?

最佳答案

我不确定您面临什么问题,但该代码应该足以使某些功能正常工作。也许输出不是您所期望的,所以我将对此进行一些扩展。

Assuming this is the WSDL of that service (因为网络服务本身无法工作),为了调用它并添加安全 header ,您可以这样做:

import datetime
from zeep import Client
from zeep.wsse.username import UsernameToken
from zeep.wsse.utils import WSU
from zeep.plugins import HistoryPlugin
from lxml import etree

def print_history(h):
    print(etree.tostring(h.last_sent["envelope"], encoding = "unicode", pretty_print = True))
    print(etree.tostring(h.last_received["envelope"], encoding = "unicode", pretty_print = True))

timestamp_token = WSU.Timestamp()
today_datetime = datetime.datetime.today()
expires_datetime = today_datetime + datetime.timedelta(minutes = 10)

timestamp_elements = [
    WSU.Created(today_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")),
    WSU.Expires(expires_datetime.strftime("%Y-%m-%dT%H:%M:%SZ"))
]

timestamp_token.extend(timestamp_elements)
user_name_token = UsernameToken('username', 'password', timestamp_token = timestamp_token)

history = HistoryPlugin()
client = Client(
     'http://www.webservicex.net/ConvertSpeed.asmx?WSDL', 
     wsse = user_name_token,
     plugins = [history]
)

response = client.service.ConvertSpeed(100.00, 'kilometersPerhour', 'milesPerhour')

print_history(history)

对服务的调用将产生以下 SOAP 消息:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken>
        <wsse:Username>username</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
      </wsse:UsernameToken>
      <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsu:Created>2022-03-20T14:33:15Z</wsu:Created>
        <wsu:Expires>2022-03-20T14:43:15Z</wsu:Expires>
      </wsu:Timestamp>
    </wsse:Security>
  </soap-env:Header>
  <soap-env:Body>
    <ns0:ConvertSpeed xmlns:ns0="http://www.webserviceX.NET/">
      <ns0:speed>100.0</ns0:speed>
      <ns0:FromUnit>kilometersPerhour</ns0:FromUnit>
      <ns0:ToUnit>milesPerhour</ns0:ToUnit>
    </ns0:ConvertSpeed>
  </soap-env:Body>
</soap-env:Envelope>

如果您想使用 zeep,我建议您将其与您尝试调用的真实服务一起使用,而不是与互联网上不可用的某些示例一起使用。我猜想在 zeep 文档中他们需要一些示例服务来调用,但我什至不确定该服务是否需要身份验证 header 。

关于python - 带有时间戳标记的 UsernameToken || python || WS-安全性 (WSSE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71509211/

相关文章:

android - 我如何安全地(间接地)查询 android 中的 postgresql 数据库?

soap - 寻找 Java 库/API 来为带有附件的 SOAP 消息实现 WS-Security(SwA)

security - 任何 Spring Framework 对 REST 安全性的支持?

python - 为什么[:1] and [0] do not generate the same result?

python - 写入现有的 excel 文件

python - 如何用值填充 QListView 并显示数据?

wcf - IBM DataPower 3.7.1.x 与 WCF 客户端相关的问题

python - "pip install Django"给出异常

使用 RESTful Web 服务的 Tomcat 7 与 ehCache 独立服务器 (Glassfish) 配置

web-services - 将 CXF 与 Apache Camel 结合使用时,如何设置 WS-Addressing MessageId header ?