0

SOAPUI ( www.soapui.org )を使用してリモート Web サービスに正常に接続できました。しかし、CF9.2 から正常に呼び出すことができません。

これが私のCFC関数全体です。動的変数がありますが、soapUI インターフェイスで出力をテストしたところ、動作しました。

<cffunction name="getOrganisation" access="remote" returnType="any" output="true">

     <cfargument name="iPageNumber" type="any" required="false" default="0">
     <cfargument name="iPageSize" type="any" required="false" default="0">
     <cfargument name="bCurrentNamesOnly" type="boolean" required="false" default="1">
     <cfargument name="bExcludeNotRtos" type="boolean" required="false" default="0">
     <cfargument name="bExcludeRtoWithoutActiveRegistration" type="boolean" required="false" default="0">
     <cfargument name="sFilter" type="any" required="false" default="">
     <cfargument name="bIncludeCode" type="boolean" required="false" default="1">
     <cfargument name="sRegistrationManagers" type="any" required="false" default="">
     <cfargument name="sClassificationFilters" type="any" required="false" default="">
     <cfargument name="sScheme" type="any" required="false" default="">

     <cfset var endpoint = "https://ws.staging.training.gov.au/Deewr.Tga.WebServices/OrganisationService.svc/Organisation">

     <cfsavecontent variable="soapBody">
          <cfoutput>
               <soapenv:Envelope
                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                    xmlns:ser="http://training.gov.au/services/" 
                    xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> 
                   <soapenv:Header/>               
                        <soapenv:Body>        
                        <ser:Search>
                            <ser:request>
                                <ser:PageNumber>#arguments.iPageNumber#</ser:PageNumber>
                                <ser:PageSize>#arguments.iPageSize#</ser:PageSize>
                                <ser:ClassificationFilters>
                                   <ser:ClassificationFilter>
                                      <ser:Scheme>#arguments.sScheme#</ser:Scheme>
                                      <ser:Values>
                                         <cfif len(arguments.sClassificationFilters)>
                                            <cfloop list="#arguments.sClassificationFilters#" index="item">
                                                <arr:string>#item#</arr:string>
                                            </cfloop>
                                        </cfif>
                                      </ser:Values>
                                   </ser:ClassificationFilter>
                                </ser:ClassificationFilters>
                                <ser:CurrentNamesOnly>#arguments.bCurrentNamesOnly#</ser:CurrentNamesOnly>
                                <ser:ExcludeNotRtos>#arguments.bExcludeNotRtos#</ser:ExcludeNotRtos>
                                <ser:ExcludeRtoWithoutActiveRegistration>#arguments.bExcludeRtoWithoutActiveRegistration#</ser:ExcludeRtoWithoutActiveRegistration>
                                <ser:Filter>#arguments.sFilter#</ser:Filter>
                                <ser:IncludeCode>#arguments.bIncludeCode#</ser:IncludeCode>
                                <ser:RegistrationManagers>
                                   <cfif len(arguments.sRegistrationManagers)>
                                        <cfloop list="#arguments.sRegistrationManagers#" index="item">
                                            <arr:string>#item#</arr:string>
                                        </cfloop>
                                    </cfif>
                                </ser:RegistrationManagers>
                             </ser:request>
                        </ser:Search>
                    </soapenv:Body>
                </soapenv:Envelope>
            </cfoutput>            
        </cfsavecontent>

        <cfhttp
                url="#endpoint#" 
                method="post"
                username="#variables.username#"
                password="#variables.password#">

                <cfhttpparam type="header" name="accept-encoding" value="no-compression" />
                <cfhttpparam type="xml" value="#trim(soapBody)#"/>

        </cfhttp>

       <cfdump var="#cfhttp.FileContent#"><cfabort>

      <cfreturn cfhttp.FileContent>
</cffunction>

これを実行すると、次のエラーが表示されます。

An error occurred when verifying security for the message.

以下は、完全な戻り xml です。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <s:Fault>
            <faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode>
            <faultstring xml:lang="en-AU">An error occurred when verifying security for the message.</faultstring>
        </s:Fault>
    </s:Body>
</s:Envelope> 

したがって、これは認証の問題のようです。

SoapUI リクエスト画面は次のとおりです。

ここに画像の説明を入力

では、soapUI 呼び出しをエミュレートするために、cfhttp または cfinvoke をどのように作成すればよいのでしょうか。

編集

SOAP リクエスト XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://training.gov.au/services/" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:Search>
         <ser:request>
            <ser:PageNumber>0</ser:PageNumber>
            <ser:PageSize>0</ser:PageSize>
            <ser:ClassificationFilters>
               <ser:ClassificationFilter>
                  <ser:Scheme></ser:Scheme>
                  <ser:Values>
                     <arr:string></arr:string>
                  </ser:Values>
               </ser:ClassificationFilter>
            </ser:ClassificationFilters>
            <ser:CurrentNamesOnly>true</ser:CurrentNamesOnly>
            <ser:ExcludeNotRtos>0</ser:ExcludeNotRtos>
            <ser:ExcludeRtoWithoutActiveRegistration>0</ser:ExcludeRtoWithoutActiveRegistration>
            <ser:Filter></ser:Filter>
            <ser:IncludeCode>1</ser:IncludeCode>
            <ser:RegistrationManagers>
               <arr:string></arr:string>
            </ser:RegistrationManagers>
         </ser:request>
      </ser:Search>
   </soapenv:Body>
</soapenv:Envelope>

編集2

さらに詳しい情報:

4

3 に答える 3

0

cfhttp タグの属性としてではなく、cfhttpparam タグにユーザー名とパスワードを投稿する必要があると思います。

于 2012-07-31T01:01:07.323 に答える
0

はい、最初は Oasis セキュリティ ヘッダーを渡していませんでした。ただし、これまでの答えはおそらくうまくいかないでしょう。Oasis 標準では、user/password/nonce/digest/created および encoding 属性のさまざまな組み合わせが可能です。

お気づきかもしれませんが、Axis 1 ライブラリ (CF9 および下位ユーザーの Axis 1 (バージョン 1.1-1.4)。CF10 には Axis 2 (Axis バージョン 1.6) もあります)。したがって、Oasis ヘッダーを送受信するには、POST (cfhttp/http) する必要があります。Axis 1 ライブラリーは、ヘッダー領域の Oasis ノードを理解しようとして泣くでしょう。**

手動で投稿しているので、Matt Gifford の例と同じように、ヘッダーに Oasis ヘッダーを簡単に作成できます。

受信者が正確に何を期待しているかに応じて、次のようなものになる場合があります。

<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <wsse:UsernameToken wsu:Id="UsernameToken-15">
    <wsse:Username>
      <!-- Removed-->
    </wsse:Username>
    <wsse:Password>
      <!-- Removed-->
    </wsse:Password>
    <wsse:Nonce>
      <!-- Removed-->
    </wsse:Nonce>
    <wsu:Created>2012-07-11T02:02:48.410Z</wsu:Created>
  </wsse:UsernameToken>
</wsse:Security>

またはこれ(初期のクラッディング方法の事前出力から):

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
  <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" >
  <wsse:Username>#Arguments.szUserName#</wsse:Username>
  <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0##PasswordText">#Arguments.szPassword#</wsse:Password>
  </wsse:UsernameToken>
</wsse:Security>

またはこれ(最終出力):

<wsse:Security soapenv:mustUnderstand="1"xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  <wsse:UsernameToken wsu:Id="UsernameToken-974900"xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:Username>SuperJellyMan</wsse:Username>
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">jellybeanboom</wsse:Password>
    <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">SmVsbHlCZWFuQm9vbTk3NDkwMA==</wsse:Nonce>
    <wsu:Created>2012-07-26T17:00:34Z</wsu:Created>
  </wsse:UsernameToken>
</wsse:Security>

などなど。これをより動的に行うために Java ライブラリを呼び出す人々を見てきました。ナンスを作成し、xml タイムスタンプをフォーマットするための簡単なメソッドをいくつか作成しました。しかし、基本的には、適切な Oasis 属性と xsd 参照を使用して xml で必要な値を覆い、それを手動投稿のリクエストのヘッダーに挿入するために、ある種の関数またはその他のヘルパー メソッドを構築するのは非常に簡単です。

トリッキーな部分は、Oasis のセキュリティ ヘッダーに何が必要かを正確に知ることです。xsd は、Oasis の標準に従って何が受け入れられるかを示すだけであり、必ずしもそれらが使用しているもの (およびその組み合わせ) を示しているわけではありません。それらからそれを取得できる場合は、Oasis のドキュメントから非常に簡単にまとめることができます。

通常、組み合わせは User/Pwd です (最初の例)。Nonce が使用される場合、非常に頻繁に Password Digest も使用され (パスワードは ##PasswordText の代わりに ##PasswordDigest を取得します)、作成された時間とパスワードのエンコードされたハッシュです (詳細については、Oasis のドキュメントを参照してください)。

しかし、私が取り組んだ最後のプロジェクトには、プレーン テキストの pwd とダイジェストのない nonce がありました。ノンスは偽のリクエストをより困難にし、受信者がデコードして検証と比較する必要がある非クリアテキストパスワードを使用することになっているため、厳密には論理的ではありません...したがって、彼らが望むものは完全にサービス次第です/使用/必要。

作成した Oasis ヘッダーを SoapUI に貼り付けて、同じ応答から彼らが何を必要としているか、何を望んでいるかをすぐに把握できるはずです。

ユーザー/パスワードを (テキストとして) 指定している場合、これらの例の 1 つ (おそらく 2 番目の例) が機能し、ナンスと作成された要素を渡さないことがわかる場合があります。

** Oasis が実際の SOAP メソッド (手動投稿ではなく Web サービス スタブ) を使用して CF9 以下で使用されている場合の楽しい参照用の Axis 1 障害は次のとおりです:**

Web サービス操作を呼び出すときに返される障害は次のとおりです。

AxisFault faultCode: { http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd }InvalidSecurity faultSubcode: faultString: メッセージのセキュリティを検証中にエラーが発生しました. faultActor: faultNode:
faultDetail: { http://xml.apache.org/axis/ }stackTrace:メッセージのセキュリティを確認中にエラーが発生しました。org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:221) で org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:128) で org.apache.axis.encoding.DeserializationContext.endElement (DeserializationContext.java:1087)
org.apache.xerces.parsers.AbstractSAXParser.endElement(不明なソース) org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(不明なソース) org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(不明なソース) org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument (不明なソース) で org.apache.xerces.parsers.XML11Conf...

[編集] 同様の別の Web サービスに取り組んでいるため、もう少し情報があります。あなたの [SOAP] xml はおそらく機能していません。私もsoapUIを使用していますが、適切な場所にセキュリティヘッダー値を追加しない限り、サービスは受信した応答(「InvalidSecurity」)を正確に返すため、このxmlが複製しようとしているものであるかどうかはよくわかりません。また、ヘッダーを適切に生成し、javastubbed Web サービスで呼び出された createObject() に追加するヘッダーを作成するための単純な cf ベースのスクリプト バージョンの作成にも成功しました。

doc = xmlNew();
doc['Security'] = XmlElemNew(doc,'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', 'Security');
doc.Security['UsernameToken'] = XmlElemNew(doc,  'UsernameToken');
doc.Security.UsernameToken['Username'] = XmlElemNew(doc,  'Username');
doc.Security.UsernameToken.username.XmlText = "TESTERDUDE" ;
doc.Security.UsernameToken.username.XmlAttributes["xsi:type"] = "xsd:string";
doc.Security.UsernameToken['Password'] = XmlElemNew(doc, 'Password');
doc.Security.UsernameToken.password.XmlText = "YetAnotherPassword";
doc.Security.UsernameToken.password.XmlAttributes["xsi:type"] = "xsd:string";
doc.Security.UsernameToken.password.XmlAttributes["Type"] = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0##PasswordDigest";
doc.Security.UsernameToken['Nonce'] = XmlElemNew(doc, 'Nonce');
doc.Security.UsernameToken.nonce.XmlText = "tKUH8ab3Rokm4t6IAlgcdg9yaEw="; // This would be generated if needed
doc.Security.UsernameToken.nonce.XmlAttributes["xsi:type"] = "xsd:string";
doc.Security.UsernameToken['Created'] = XmlElemNew(doc, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", 'Created');
doc.Security.UsernameToken.created.XmlText = "2010-08-10T10:52:42Z";
doc.Security.UsernameToken.created.XmlAttributes["xsi:type"] = "xsd:string";
addSOAPRequestHeader(ws, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", doc);

これにより、[xml リクエスト全体を取得する getSoapRequest() を使用してサーバー側の xml から取得] が適切に生成されます。

<soapenv:Header>
  <Security soapenv:actor="" soapenv:mustUnderstand="0" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <UsernameToken>
      <Username xsi:type="xsd:string">TESTERDUDE</Username>
      <Password xsi:type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">My Password is my Voice</Password>
      <Nonce xsi:type="xsd:string">tKUH8ab3Rokm4t6IAlgcdg9yaEw=</Nonce>
     <Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xsi:type="xsd:string">2010-08-10T10:52:42Z</Created>
    </UsernameToken>
  </Security>
</soapenv:Header>
于 2012-08-23T23:02:22.757 に答える
0

SOAPUI は素晴らしいツールであり、SOAP リクエストをデバッグしたり、静的な .wsdl ファイルから ColdFusion コンポーネントに転送したりする際に最近よく使用しています。

最初に確認するのは、エラー メッセージ自体です。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <s:Fault>
      <faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode>
      <faultstring xml:lang="en-AU">An error occurred when verifying security for the message.  </faultstring>
    </s:Fault>
  </s:Body>
</s:Envelope>

faultcode ノードには、OASIS セキュリティ名前空間ドキュメントへのリンクが含まれています。

http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd

ブラウザーでそれを表示すると、必要なセキュリティ値を確認し、命名規則を明確にすることができます。したがって、このことから、次の形式で以下を送信する必要があることが確認できます。

  • ユーザー名
  • パスワード

SOAPUI でテストしているリクエストにアクセスできない場合、ユーザー名とパスワードの値がプロパティ ウィンドウに表示されていることもわかります (上記のインターフェイスから画面を取得します)。

これらの値は、SOAPUI の要求の XML 内に設定されていますか? おそらくSOAPリクエストヘッダーで、次のようになります。

<soapenv:Header>
  <authInfo xsi:type="soap:authentication">
    <Username xsi:type="xsd:string">?</Username>
    <Password xsi:type="xsd:string">?</Password>
  </authInfo>
</soapenv:Header>

その場合は、soapBody 変数を作成するときに、ColdFusion コンポーネントにこのヘッダーを含める必要もあります。

また、SOAP リクエストの URL をブラウザで直接表示して、期待される変数を確認できますか?

https://ws.staging.training.gov.au/Deewr.Tga.WebServices/OrganisationService.svc/Organisation

CFC と soapBody の全体的な構造は適切に見えるので、SOAPUI で実行中のファイルにアクセスして実行を確認しないと、デバッグして回答を提供するのは少し難しいでしょう。

上記の可能性をすべて除外しても問題が解決しない場合は、お知らせください。

于 2012-07-31T08:20:41.947 に答える