2

我正在尝试使用 Ruby 和 Savon来关注这里的讨论。我能够检索会话 ID,但每当我从需要身份验证(跟踪器)的客户端执行请求时,我都会收到授权失败错误。

require 'Savon'

tracker_url = 'http://myserver/polarion/ws/services/TrackerWebService?wsdl'
session_url = 'http://myserver/polarion/ws/services/SessionWebService?wsdl'

# todo handle bad login credentials gracefully
session_client = Savon.client(wsdl: session_url)
response = session_client.call(:log_in, message: {user_name: 'lsimons', password: 'mypassword'})
session_id = response.header[:session_id]

puts "Session ID: #{session_id}"

tracker_client = Savon.client(wsdl: tracker_url, soap_header: {"session" => session_id},     headers: {"sessionID" => session_id})

puts "Requesting Workitem"
begin
    tracker_client.call(:get_work_item_by_id, message: {project_id: 'myProject', workitem_id: 'myWorkitem'})
rescue
    puts "Client call failed"
end

此代码为 tracker_client 创建以下 SOAP 请求:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="http://ws.polarion.com/TrackerWebService-impl" xmlns:ins1="http://ws.polarion.com/types" xmlns:ins2="http://ws.polarion.com/TrackerWebService-types" xmlns:ins3="http://ws.polarion.com/ProjectWebService-types" xmlns:tns1="http://ws.polarion.com/TrackerWebService" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <env:Header>
        <session>2164640482421325916</session>
    </env:Header>
    <env:Body>
        <tns1:getWorkItemById>
            <ins0:projectId>myProject</ins0:projectId>
            <ins0:workitemId>myWorkitem</ins0:workitemId>
        </tns1:getWorkItemById>
    </env:Body>
</env:Envelope>

但是,在论坛讨论中,sessionID 元素出现在标题之前。我认为标准 SOAP 不可能做到这一点?有没有办法通过 Savon 实现这一目标,还是我误解了论坛讨论?

4

2 回答 2

3

我在同一个线程之后遇到了同样的问题。这就是我使它工作的方式(通过复制 log_in 请求的响应标头):

tracker_client = Savon.client(
  wsdl: tracker_url,
  soap_header: {
    "ns1:sessionID" => session_id,
    :attributes! => {
      "ns1:sessionID" => {
        "env:actor"           => "http://schemas.xmlsoap.org/soap/actor/next",
        "env:mustUnderstand"  => "0",
        "xmlns:ns1"           => "http://ws.polarion.com/session"
      }
    }
  }
)
于 2013-05-31T07:42:34.270 回答
0

老问题,但我想我可以添加一些信息以希望对某人有所帮助。

lolsoap用来和polarion说话。在上面生成的文档中,该sessionID元素已从任何名称空间和属性中删除。评估也是正确的,actor属性mustUnderstand似乎无关紧要。

要正确添加标题,尽管有所有绒毛,需要获取它,Nokogiri::XML::Node然后dup将其添加到文档的标题中。这是nokogiri/libxml2中的一个错误,添加子元素通常会破坏命名空间,除非在添加 [1] 之前克隆 Node。

lolsoap其中完成了类似的操作:

auth_header = login_response.nokogiri_doc.xpath("//*[local-name()='sessionID']")[0].dup
other_request.header.__node__ << auth_header

请注意dup操作。header.__node__只是Nokogiri::XML::Element随机 SOAP 请求的标头。

dup操作将所需元素添加到另一个元素中,并正确定义了所有必要的命名空间和属性。

我不知道是否savon允许直接触摸请求 XML,但我想确实如此。因此 HTH

[1] https://github.com/sparklemotion/nokogiri/issues/1200

于 2016-06-09T10:34:09.000 回答