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



当使用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),我会遇到同样的问题。但是,如果我将此值更改为与 WSDL 一起发送的示例中的值http://schemas.xmlsoap.org/ws/2002/07/secext,则请求成功完成,并且我从 API 获得成功响应。

我已经尝试了很多事情,包括在安全元素标头中显式定义命名空间:

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 中,就可以工作。

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

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

最新更新