我正在尝试使用suds访问的肥皂1.1 / 1.2网络服务。
不幸的是,该服务将身份验证令牌放入响应soap标头中。
是否可以以某种方式访问标题?
我知道可以在请求中设置自定义soap标头,但这不是我正在寻找的。 p>
答案 0 :(得分:4)
我一直在使用(仍然维护的)suds-jurko分支,并因为client.last_received()
在分叉后被删除而遇到麻烦。所以我必须想出一种替代方法来访问标题。
幸运的是,您可以使用消息插件来存储已解析的文档,然后通过插件访问标头。为了方便起见,您可以基于service-method处理标头,而不是使用xml文档中的原始值,以获得正确的类型/结构化值。
from suds.plugin import MessagePlugin
class HeaderPlugin(MessagePlugin):
def __init__(self):
self.document = None
def parsed(self, context):
self.document = context.reply
def get_headers(self, method):
method = method.method
binding = method.binding.output
rtypes = binding.headpart_types(method, False)
envns = ('SOAP-ENV', 'http://schemas.xmlsoap.org/soap/envelope/')
soapenv = self.document.getChild('Envelope', envns)
soapheaders = soapenv.getChild('Header', envns)
nodes = soapheaders.children
if len(nodes):
resolved = rtypes[0].resolve(nobuiltin=True)
return binding.unmarshaller().process(nodes[0], resolved)
return None
用法:
from suds.client import Client
hp = HeaderPlugin()
client = Client(wsdl, plugins=[hp])
response = client.service.LoremIpsum()
headers = hp.get_headers(client.service.LoremIpsum)
示例输出:
>>> headers
(AuthenticationResponseHeader){
sessionKey = "a631cd00-c6be-416f-9bd3-dbcd322e0848"
validUntil = 2030-01-01 01:01:01.123456+01:00
}
>>> headers.validUntil
datetime.datetime(2030, 1, 1, 1, 1, 1, 123456, tzinfo=<suds.sax.date.FixedOffsetTimezone object at 0x7f7347856be0>)
答案 1 :(得分:2)
您可以执行类似
的操作print client.last_received().getChild("soap:Envelope").getChild("soap:Header")
.getChild("ResponseHeader").getChild("resultCode").getText()
以上内容读取soap头中的字段resultCode。您必须为每个字段执行此操作。这是我所知道的后门左侧读取标题。
有关详细信息,请查看soap headers with suds
答案 2 :(得分:0)
Towr的类插件运行良好,但是当你在Soapheader Response中有多个obj时它会有问题。 他的代码只得到第一个对象。
以下是改进Towr课程的代码:
class HeaderPlugin(MessagePlugin):
def __init__(self):
self.document = None
def parsed(self, context):
self.document = context.reply
def get_headers(self, method):
Result = {}
method = method.method
binding = method.binding.output
SHeaderElem = binding.headpart_types(method, False)
envns = ('SOAP-ENV', 'http://schemas.xmlsoap.org/soap/envelope/')
soapenv = self.document.getChild('Envelope', envns)
soapheaders = soapenv.getChild('Header', envns)
SHeaderNodes = soapheaders.children
for Elem in SHeaderElem:
for Node in SHeaderNodes:
if(Node.name == Elem.name):
ElemRes = Elem.resolve(nobuiltin=True)
NodeRes = binding.unmarshaller().process(Node, ElemRes)
Result[Elem.name] = NodeRes
return Result
#
要更好地理解,请参阅示例。 如果你收到这个肥皂反应:
<soap-env:Envelope xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<soap-env:Header>
<eb:MessageHeader eb:version="1.0" soap-env:mustUnderstand="1">
<!-- -->
</eb:MessageHeader>
<wsse:Security>
<!-- -->
</wsse:Security>
</soap-env:Header>
<soap-env:Body>
<!-- -->
</soap-env:Body>
</soap-env:Envelope>
函数get_headers将返回一个这样的字典:
SoapHeadersResp = {'MessageHeader':MessageHeaderObj, 'Security':SecurityObj}
要使用这个类,只需按照Towr所说的步骤,用这个替换他的HeaderPlugin类。