Pete Robinson
Pete Robinson

Reputation: 39

Change xmlns:wsse namespace in SOAP request with Python Zeep

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

Answers (2)

darthtye
darthtye

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

Pete Robinson
Pete Robinson

Reputation: 39

Resolved by switching to using a different SOAP library.

Upvotes: 0

Related Questions