【问题标题】:Change xmlns:wsse namespace in SOAP request with Python Zeep使用 Python Zeep 在 SOAP 请求中更改 xmlns:wsse 命名空间
【发布时间】:2019-04-10 16:11:32
【问题描述】:

使用 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 中做到这一点(我对不同的 SOAP 包持开放态度,尽管 Zeep 似乎是最积极维护的)?还是我的请求格式中完全遗漏了可能导致此问题的某些内容?

代码如下。提前谢谢!

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 中即可。

【问题讨论】:

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


    【解决方案1】:

    通过切换到使用不同的 SOAP 库来解决。

    【讨论】:

    • 你最终使用了什么库?什么对你有用?
    【解决方案2】:

    花了我 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")
    

    【讨论】:

    • 很好的答案,拯救了我的一天。在ns.py 中,zzep 对 WSSE URI 进行了硬编码,此后由 gSOAP 构建的 SOAP 服务器拒绝了这一点——我别无选择,只能自己填充标头。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    相关资源
    最近更新 更多