使用Python Zeep更改SOAP请求中的xmlns:wsse命名空间

时间:2019-04-10 16:11:33

标签: python python-3.x soap xml-namespaces zeep

使用Zeep(Python3.7)将数据发送到SOAP API时,生成的wsse:Security头为http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd

其结果是错误:

zeep.exceptions.Fault: SOAP Security Header UsernameToken is required for operation 'ProcessMessage'

如果我随后获取原始请求XML并将其发送到API(通过SOAPUI),则会遇到相同的问题。但是,如果我将此值更改为示例中与http://schemas.xmlsoap.org/ws/2002/07/secext的WSDL一起发送的值,则请求成功完成,并且从API获得成功响应。

我尝试了很多事情,包括在Security元素头中明确定义名称空间:

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()),
            ])
        )
    ])
)

但是,这似乎无法解决问题。

我也尝试过:

client.set_default_soapheaders([header_value])

再次,没有喜悦。

在Zeep中有没有办法做到这一点(尽管Zeep似乎是最活跃的维护工具,但我对其他SOAP包持开放态度)?还是我的请求格式中缺少某些可能导致此问题的内容?

下面的代码。预先谢谢你!

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)

就生成的XML而言,以上示例给出了以下内容:

<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>

哪个不起作用

但是,只需在原始XML中将wsse:Security xmlns:wsse的值更改为http://schemas.xmlsoap.org/ws/2002/07/secext,然后将其粘贴到SOAPUI,即可。

2 个答案:

答案 0 :(得分:0)

通过切换为使用其他SOAP库来解决。

答案 1 :(得分:0)

花了我2天的时间,但为此找到了解决方法。 拿

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()),
        ])
    )
])

然后将这样的名称空间URL信息添加到所有属性中,而不仅仅是组

  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()),
        ])
    )
])

还要确保将名称空间放在这样的客户端上

client.set_ns_prefix('wsse', "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")