带时间戳令牌的用户名令牌 || 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.
我应该使用 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.