带时间戳令牌的用户名令牌 || Python || WS-安全 (WSSE)

UsernameToken with Timestamp token || Python || WS-Security (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”的库可以处理这个问题,唯一的问题是据我所知,关于它的文档很少。

带时间戳令牌的用户名令牌

要将 UsernameToken 与 Timestamp 令牌一起使用,首先您需要一个 WSU.Timestamp() 的实例,然后使用包含 WSU.Created() 和 [=34= 的列表扩展它]() 元素,最后将其作为 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,我建议您将它与您尝试调用的真实服务一起使用,而不是与来自 Internet 的一些不可用的示例一起使用。我猜在 zeep 文档中他们需要调用一些示例服务,但我什至不确定该服务是否需要身份验证 header.