【问题标题】:Accessing response soap header using suds使用 suds 访问响应肥皂标题
【发布时间】:2012-12-12 16:55:27
【问题描述】:

我正在尝试使用 suds 访问一个 soap 1.1/1.2 网络服务。

不幸的是,服务将身份验证令牌放在响应肥皂头中。

是否有可能以某种方式访问​​标题?

我知道可以在请求中设置自定义soap标头,但这不是我想要的。

【问题讨论】:

    标签: python soap suds


    【解决方案1】:

    我一直在使用(仍然维护的)suds-jurko 分支,但遇到了麻烦,因为client.last_received() 在分叉后很早就被删除了。所以我必须想出另一种访问标题的方法。

    幸运的是,您可以使用消息插件来存储解析后的文档,然后通过插件访问标题。为了更加方便,您可以根据服务方法处理标头,而不是使用 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>)
    

    【讨论】:

      【解决方案2】:

      你可以这样做

      print client.last_received().getChild("soap:Envelope").getChild("soap:Header")
      .getChild("ResponseHeader").getChild("resultCode").getText()
      

      上面读取了soap头中的一个字段resultCode。您必须为每个字段执行此操作。据我所知,这是阅读标题的后门。

      详情请看soap headers with suds

      【讨论】:

      • 干杯!我想更干净的方法是:client.last_received().getChildAtPath("soap:Envelope/soap:Header/ResponseHeader/resultCode").getText(),但它仍然感觉笨拙。
      • 是的,同意。我以前没用过..AtPath。清洁
      【解决方案3】:

      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 响应:

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

      【讨论】:

        猜你喜欢
        • 2011-08-11
        • 2011-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多