pythonsuds

Add Namespace to the default WSSE Security Object in Suds


I understand how to add a header to the SOAP request. But that generates a header that doesn't match the one I need to pass. That returns this header:

   <SOAP-ENV:Header>
      <wsse:Security mustUnderstand="true">
         <wsse:UsernameToken>
            <wsse:Username>CABLE</wsse:Username>
            <wsse:Password>CABLE</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </SOAP-ENV:Header>

However, I need to modify the namespace of that header to pass the particular namespace for the Security object and the UsernameToken object. I can't seem to figure out how to override the default values supplied.

<soapenv:Header>
 <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
       http://schemas.xmlsoap.org/ws/2002/07/secext
 <wsse:UsernameToken xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
 <wsse:Username>CABLE</wsse:Username>
 <wsse:Password Type="wsse:PasswordText">CABLE</wsse:Password>
 </wsse:UsernameToken>
 </wsse:Security>
</soapenv:Header>

Here is the Python Code to generate the above

security = Security()
token = UsernameToken('CABLE', 'CABLE')
security.tokens.append(token)
client.set_options(wsse=security)

Solution

  • Figured it out. Here is the answer. Just need to use the ns argument

    def createWSSecurityHeader(username,password):
        # Namespaces
        wsse = ('wsse', 'http://schemas.xmlsoap.org/ws/2002/07/secext')
    
        # Create Security Element
        security = Element('Security', ns=wsse)
    
        # Create UsernameToken, Username/Pass Element
        usernametoken = Element('UsernameToken', ns=wsse)
        uname = Element('Username', ns=wsse).setText(username)
        passwd = Element('Password', ns=wsse).setText(password)
    
        # Add Username and Password elements to UsernameToken element
        usernametoken.insert(uname)
        usernametoken.insert(passwd)
    
        security.insert(usernametoken)
        return security