web-dev-qa-db-ja.com

WSDLへのSOAP暗黙ヘッダーの追加

私の質問はこれに似ています。 WSDLがSOAPヘッダーを定義していない場合にSOAPヘッダーを渡す方法は? しかし異なります。

私が使用するWebサービスの場合、すべての方法でSOAPヘッダー内のクリアテキストで送信される認証が必要です。ただし、私のWSDLにはSOAPヘッダー情報が含まれていません。カスタムプラットフォームツールを使用しています。 WSDLからコードを生成するために使用する必要があります。ヘッダー情報が利用できないため、生成されたクラスを直接使用できません。ヘッダーに対応するためにコードを手動で変更したくありません。

WSDLでSOAPヘッダーを指定してみましたが、正しい名前空間を取得できませんでした。WSDLはこちら https://stage.totalcheck.sensis.com.au/service/webservice?wsdl およびSOAPヘッダーは次のとおりです:

    <soapenv:Header>
        <wsse:Security>
            <wsse:UsernameToken>
                <wsse:Username>username</wsse:Username>
                <wsse:Password>password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
   </soapenv:Header>

誰かが私を助けてくれますか?ありがとう!

16
Vid L

概念的な観点から見ると、WSDLはヘッダーを定義するものではありません。 WSDLは、操作、メッセージ、バインディング、エンドポイントなど、サービスの機能面を定義するためだけのものです。メッセージとバインディングは、メッセージのペイロードをエンコードおよびフォーマットする方法を定義します。

SOAPメッセージのヘッダーはペイロードに属していません。これらは通常、SOAPプロセッサの非機能プロパティを構成するために使用されます。セキュリティはそのようなものです非機能プロパティ。ペイロードの機能面は影響を受けません。通信が保護され、サービス実装ではなくWSツールスタックがそれを処理することを保証するだけです。

したがって、欠落している部分は、WSDLサービスにいくつかの非機能要件を添付することを可能にする標準になりました。その結果、コードジェネレーターは、必要に応じて非機能プロパティを実現するために送信する必要があるヘッダーを自動的に導き出したり、理解したりできます。 -ヘッダーフィールドを手動で処理する必要はありません。この標準は存在し、 WS-Policy と呼ばれます。ポリシーには通常、プロバイダーとコンシューマーの両方が満たす必要がある一連の要件を公開する一連の代替案が含まれています。 2つのサービスが相互に対話することになっている場合、両方のポリシーが取られ、いわゆる「有効なポリシー」が計算されます。一般的な非機能要件を定義します。この情報を使用して、プロバイダーとコンシューマーは、WS-Securityヘッダーなどの必要なヘッダーを追加するように自分自身を構成できます。 WS-SecurityPolicy は、使用できる一連のポリシーも定義します。 WS-PolicyAttachment は、このようなポリシーをWSDLにアタッチする方法を定義します。

WS-Policiesを処理できるコードジェネレーターがあります。 MetroまたはAxis2

20
vanto

SoapHeader属性を使用してwsdlから生成されたプロキシクラスのメソッドを修飾することで、メソッド呼び出しにSOAPヘッダー情報を追加できます。

たとえば、「Web参照を追加」すると、wsdl.exeはWebサービス参照のクライアントプロキシクラスReference.csを生成します。上記のリンクに https://stage.totalcheck.sensis.com.au/service/webservice?wsdl 生成されたreference.csクライアントプロキシのメソッドに変換されるメッセージSuggestAddressがありますVisual StudioからWeb参照を追加するときのコードファイル。デフォルトでは、このメソッドが呼び出されると、SOAPエンベロープにヘッダーはありません。 SoapHeaderをこのリクエストのエンベロープに追加するには、[SoapHeader( "Security")]属性をReference.cs生成クラスのSuggestAddressメソッドの先頭に追加します。ここで、「Security」はSoapHeader基本クラスから継承するクラスです。

上記の必須のセキュリティSoapHeaderの例では、次のクラスを作成します。

public partial class Security : SoapHeader
{
    public UserNameToken UserNameToken { get; set; }
}

public partial class UserNameToken
{
    public string UserName { get; set; }
    public string Password { get; set; }
}

次に、次のようにreference.csのSuggestAddressメソッドを装飾します。

[SoapHeader("Security")]
public suggestAddressesResult suggestAddresses([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] addressSearch search) {
        object[] results = this.Invoke("suggestAddresses", new object[] {search});
        return ((suggestAddressesResult)(results[0]));
    }

これにより、suggestAddressメソッドが呼び出されたときに作成されたすべてのエンベロープに、上記のようなセキュリティヘッダーが含まれるようになります。

<soapenv:Header>
    <wsse:Security>
        <wsse:UsernameToken>
            <wsse:Username>username</wsse:Username>
            <wsse:Password>password</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
4
Roger

この質問を使用して自分自身を支援する上での鍵は、問題のヘッダーがWS-Security標準のヘッダーであることを(一部指摘したように)認識することでした。

プロキシ生成ツールが「カスタム」の場合、WS-Securityのヘッダーを自動的に追加するスイッチがある可能性があるのは当然のようです。ただし、WSDL.exe(Visual Studioでは「Web参照の追加」)を使用している場合は、代わりにsvcutil.exe(「サービス参照の追加」)を検討してください。

WCFプロキシを使用する場合は、特定の構成を上書きして、WCFがヘッダーを追加できるようにします。

<security mode="TransportWithMessageCredential">
    <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
    <message clientCredentialType="UserName" algorithmSuite="Default" />
</security>

そこから、パスワードを指定できます。

RemoteSvcProxy.TheirClient client = new RemoteSvcProxy.TheirClient();
client.ClientCredentials.UserName.UserName = "uname";
client.ClientCredentials.UserName.Password = "pwd";

私はあなたのカスタムツールが何であるかわかりませんが、おそらくそれが基づいているフレームワークも同様の設定オプションを持っています。

1
b_levitt