1

私はphpでこの(実用的な)例を持っています:

$usernameToken = new SoapHeaderUsernameToken( $password, $username );
$soapHeaders[] = new SoapHeader("urn:localhost-catalog", 'UsernameToken', $usernameToken);

$client = new SoapClient("my_client_url");
$client->__setSoapHeaders( $soapHeaders );

しかし、Ruby のクライアントが必要です。認証を行うことができる savon gem を使用しています。これまでのところ、次の方法があります。

def my_soap_client
    client = Savon::Client.new do
        wsdl.document = "my_client_url"
    end

    client.wsse.credentials "usr", "pass" # Adding :digest doesn't seem to help

    return client
end

# I make requests like this:
my_soap_client.request :wsdl, "getProductGroups", :parent_id => 1

使用可能なアクションを正常にリストできますが、リクエストを作成しようとすると、結果は常に"(SOAP-ENV:Client) Missing parameter"になります。また、正しい認証情報を渡すか偽の認証情報を渡すかは問題ではありません。そのため、認証が失敗すると思います。

誰かが助けてくれることを願っています!

4

2 に答える 2

2

Wireshark スニファを使用して、PHPコードが送信するSOAPリクエストをインターセプトしました。次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="urn:examples:helloservice"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:ns2="urn:localhost-catalog"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Header>
    <ns2:UsernameToken>
      <Password>pass</Password>
      <Username>login</Username>
    </ns2:UsernameToken>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <ns1:getProductGroups>
      <parentId>1</parentId>
    </ns1:getProductGroups>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

ここで、このコードがUsernameTokenヘッダーにns2名前空間を追加していることがわかります。

次に、Rubyコードを送信するSOAPリクエストをインターセプトしました。

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:wsdl="http://www.ecerami.com/wsdl/HelloService.wsdl"
              xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken wsu:Id="UsernameToken-1"
                          xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>usr</wsse:Username>
        <wsse:Password
                Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
          pass
        </wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </env:Header>
  <env:Body>
    <wsdl:getProductGroups>
       <parentId>1</parentId>
    </wsdl:getProductGroups>
  </env:Body>
</env:Envelope>

違いがわかります-UsernameTokenはセキュリティ要素にラップされており、UsernameTokenの名前空間は「http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd」です。

PHPコードはカスタム認証を使用しており、savonはwsseプロパティを介してそれをサポートしていません。Savonのソースコードを調べました。Akami.wsseを使用しており、そのコードでは名前空間を設定することはできません。これは、手動でヘッダーを作成する必要があることを意味します。必要に応じてSOAPリクエストを生成するRubyのコードは次のとおりです。

require 'savon'

client = Savon::Client.new do
  wsdl.document = "test.wsdl"
end

client.request :wsdl, "sayHello" do
    soap.namespaces["xmlns:ns2"] = "urn:localhost-catalog"
    soap.header = { "ns2:UsernameToken" =>
                          {"Password" => "pass", "Username" => "login"}
                  }
    soap.body = { :parent_id => 1 }
end

次のSOAPリクエストを生成します。

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:wsdl="http://www.ecerami.com/wsdl/HelloService.wsdl"
              xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:ns2="urn:localhost-catalog">
  <env:Header>
    <ns2:UsernameToken>
      <Password>pass</Password>
      <Username>login</Username>
    </ns2:UsernameToken>
  </env:Header>
  <env:Body>
    <wsdl:sayHello>
      <parentId>1</parentId>
    </wsdl:sayHello>
  </env:Body>
</env:Envelope>

お役に立てれば!

于 2011-12-13T15:38:06.290 に答える
0

Savon でヘッダーを設定するには、次の式を使用します。

client.request :wsdl, "getProductGroups" do
    soap.header = { :header_key => "your header goes here",
                    :attributes! => { :attr => "your attribute" }
                  }
    soap.body = { :parent_id => 1 }
end

おそらくそれがあなたを助けます。

-st

于 2011-12-11T19:23:42.643 に答える