我正在尝试使用python和zeep进行SOAP请求,我需要添加带有安全性(wsse: security)和时间戳(wsu: timestamp)标签的SOAP:Header
我有这样的代码:
from zeep import Client
from zeep.wsse import UsernameToken
from zeep.wsse import utils
from datetime import datetime, timedelta
# Create a SOAP client for the service
url = 'https://XXXXXXXXX/wsdlXXXXXX'
client = Client(url)
# Create a Object UsernameToken auth credentials
username = 'USERNAME'
password = 'PASSWORD'
token = UsernameToken(username, password)
# Add object UsernameToken to the tag wsse:Security
security = client.get_element('wsse:Security')
security_value = security(namelist=[token])
# Create a object Timestamp with date an time (now)
timestamp = utils.Timestamp()
timestamp_created = datetime.utcnow()
timestamp_expires = timestamp_created + timedelta(minutes=10)
timestamp.created = timestamp_created
timestamp.expires = timestamp_expires
# Add the tag wsu:Timestamp to the hader SOAP
timestamp_value = timestamp.xml
# add the tags in header SOAP
header = client.service._binding.create_message_header()
header.append(security_value)
header.append(timestamp_value)
# Send request SOAP with header
result = client.service.addressTown(_soapheaders=[header], arg1='28001')
我的错误是:
Traceback (most recent call last):
File "test3.py", line 16, in <module>
security = client.get_element('wsse:Security')
File "C:UsersUSERDocumentsProjectsEva Seguroscomparatupolizavenvlibsite-packageszeepclient.py", line 182, in get_element
return self.wsdl.types.get_element(name)
File "C:UsersUSERDocumentsProjectsEva Seguroscomparatupolizavenvlibsite-packageszeepxsdschema.py", line 126, in get_element
qname = self._create_qname(qname)
File "C:UsersUSERDocumentsProjectsEva Seguroscomparatupolizavenvlibsite-packageszeepxsdschema.py", line 265, in _create_qname
raise ValueError("No namespace defined for the prefix %r" % prefix)
ValueError: No namespace defined for the prefix 'wsse'
wsse
前缀缺少一个命名空间,在get_element方法中使用它们之前定义它。
下面的内容,不要忘记用WSDL的实际URL和UsernameToken
对象的正确用户名和密码替换XXXXXXXXX/wsdlXXXXXX
。
from zeep import Client, Settings
from zeep.wsse import UsernameToken
from zeep.wsse.utils import Timestamp
from datetime import datetime, timedelta
from lxml import etree
# Create a SOAP client for the service
url = 'https://XXXXXXXXX/wsdlXXXXXX'
settings = Settings(strict=False, xml_huge_tree=True)
client = Client(url, settings=settings)
# Define the required namespaces
client.wsdl.types.prefix_map['wsse'] = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
client.wsdl.types.prefix_map['wsu'] = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
# Create a Object UsernameToken auth credentials
username = 'USERNAME'
password = 'PASSWORD'
token = UsernameToken(username, password)
# Add object UsernameToken to the tag wsse:Security
security = client.get_element('wsse:Security')
security_value = security(namelist=[token])
# Create a object Timestamp with date an time (now)
timestamp = Timestamp()
timestamp_created = datetime.utcnow()
timestamp_expires = timestamp_created + timedelta(minutes=10)
timestamp.created = timestamp_created
timestamp.expires = timestamp_expires
# Add the tag wsu:Timestamp to the header SOAP
timestamp_value = timestamp.xml
# Create SOAP header
header = etree.Element("SOAP-ENV:Header", nsmap=client.wsdl.types.prefix_map)
header.append(security_value)
header.append(timestamp_value)
# Send request SOAP with header
result = client.service.addressTown(_soapheaders=[header], arg1='28001')