Reputation: 39
When using Zeep (Python3.7) to send data to a SOAP API, the wsse:Security
header generated is http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
The result of this is the error:
zeep.exceptions.Fault: SOAP Security Header UsernameToken is required for operation 'ProcessMessage'
If I then take the raw request XML and send that to the API (via SOAPUI), I get the same issue. However, if I change this value to the value that was in the example I've been sent alongside the WSDL of http://schemas.xmlsoap.org/ws/2002/07/secext
, the request completes successfully and I get a success response from the API.
I have tried many things, including explicitely defining the namespace in Security element header:
header = xsd.Element(
'{http://schemas.xmlsoap.org/ws/2002/07/secext}Security',
xsd.ComplexType([
xsd.Element(
'UsernameToken',
xsd.ComplexType([
xsd.Element('Username', xsd.String()),
xsd.Element('Password', xsd.String()),
])
)
])
)
However, this doesn't seem to fix the issue.
I've also tried:
client.set_default_soapheaders([header_value])
Again, no joy.
Is there a way of doing this within Zeep (I'm open to a different SOAP package, although Zeep seemed the most actively maintained)? Or am I missing something in my request format entirely that could be causing this issue?
Code below. Thank you in advance!
header = xsd.Element(
'Security',
xsd.ComplexType([
xsd.Element(
'UsernameToken',
xsd.ComplexType([
xsd.Element('Username', xsd.String()),
xsd.Element('Password', xsd.String()),
])
)
])
)
header_value = header(UsernameToken={'Username': user, 'Password': password})
client.service.ProcessMessage(_soapheaders=[header_value], Payload=dataobj)
In terms of generated XML, the above example gives the following:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
<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>
</wsse:Security>
</soap-env:Header>
<soap-env:Body>
### REQUEST BODY
</soap-env:Body>
</soap-env:Envelope>
Which does not work
However, by simply changing the wsse:Security xmlns:wsse
value to http://schemas.xmlsoap.org/ws/2002/07/secext
in the raw XML and pasting that into SOAPUI, that works.
Upvotes: 1
Views: 2139
Reputation: 19
Took me 2 days but found fix for this. take
header = xsd.Element(
'{http://schemas.xmlsoap.org/ws/2002/07/secext}Security',
xsd.ComplexType([
xsd.Element(
'UsernameToken',
xsd.ComplexType([
xsd.Element('Username', xsd.String()),
xsd.Element('Password', xsd.String()),
])
)
])
)
and then add the name space URL info like this to all attributes not just the group
header = xsd.Element(
'{http://schemas.xmlsoap.org/ws/2002/07/secext}Security',
xsd.ComplexType([
xsd.Element(
'{http://schemas.xmlsoap.org/ws/2002/07/secext}UsernameToken',
xsd.ComplexType([
xsd.Element('{http://schemas.xmlsoap.org/ws/2002/07/secext}Username', xsd.String()),
xsd.Element('{http://schemas.xmlsoap.org/ws/2002/07/secext}Password', xsd.String()),
])
)
])
)
also make sure you put the name space on the client like this
client.set_ns_prefix('wsse', "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")
Upvotes: 1