1

背景(少し長い)

数年前、私は顧客のために、security mode = "Transport" で clientCredentialType = "Certificate" の basicHttpBinding を使用するように構成された WCF サービスを作成しました。つまり、クライアントは (クライアント) 証明書を使用して自分自身を認証しています。このサービスは、着信証明書の拇印が有効な証明書の拇印の定義済みリストに存在するかどうかを確認するカスタム AuthorizationManager を採用しています。受信した証明書が有効であると見なされた場合、操作を続行できます (そうでない場合は、例外がスローされます)。

このサービスは約 4 年間問題なく機能しており、全員が満足しています。しかし、よくあることですが、要件が変更され、最近、アプリケーションを私の顧客のサービスに接続したいと考えている開発者から、私の顧客に連絡がありました。唯一の問題は、これらの開発者が好みのプラットフォームとして Java の変種を使用しており、現在、深刻な問題に直面していることです。簡単に言うと、Java 実装 (Metro、Axis2 など) を現在構成されているサービスで動作させることができた人は誰もいません。

先週、メッセージ clientCredentialType = "UserName" を指定してセキュリティ モード = "TransportWithMessageCredential" でバインディングを wsHttpBinding に変更することで、Java (Metro、JAX-WS) で記述されたクライアントで動作するようにしました。また、カスタム UserNamePassWordValidatorType を構成ファイルのサービス資格情報要素に追加しました。

次に、クライアントからの証明書がないため、カスタム AuthorizationManager をコメントアウトしました。

驚いたことに、今回は SoapUI と適切な Java クライアントの両方がサービスと通信できるようになりました。

(ちなみに、私たちのサービスは Windows サービスで自己ホストされています)

幸いなことに、サービスを 2 つのバインディングで構成することにしました。長い間問題なく動作している既存の basicHttpBinding と、新しくテストされた wsHttpBinding です。したがって、次のようになります。

<services>
    <service name="SuperDuperService" behaviorConfiguration="superDuperBehaviour">
        <endpoint binding="basicHttpBinding" contract="ISuperDuperService" bindingConfiguration="SecureTransport"/>
        <endpoint binding="wsHttpBinding" address="stws" contract="ISuperDuperService" bindingConfiguration="SecureTransportAndSoap"/>
        <endpoint binding="mexHttpsBinding" address="mex" contract="IMetadataExchange" />
        <host>
            <baseAddresses>
                <add baseAddress="https://<url + port>/SuperDuperService"/>
            </baseAddresses>
        </host>
    </service>
</services>
<bindings>
    <basicHttpBinding>
        <binding name="SecureTransport" maxBufferSize="2065536" maxBufferPoolSize="524288" maxReceivedMessageSize="2065536">
            <security mode="Transport">
                <transport clientCredentialType="Certificate"/>
            </security>
            <readerQuotas maxDepth="32" maxStringContentLength="6553600" maxArrayLength="2065536"
                maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        </binding>
    </basicHttpBinding>
    <wsHttpBinding>
        <binding name="SecureTransportAndSoap">
            <security mode="TransportWithMessageCredential">
                <message clientCredentialType="UserName"/>
            </security>
        </binding>
    </wsHttpBinding>
</bindings>
<behaviors>
    <serviceBehaviors>
        <behavior name="superDuperBehaviour">
            <serviceCredentials>
                <!-- The following element specifies the certificate use by this service for HTTPS (SSL) based transport security -->
                <serviceCertificate findValue="<some identifier>"
                        storeLocation="LocalMachine"
                        storeName="My"
                        x509FindType="FindBySubjectName" />
                <userNameAuthentication userNamePasswordValidationMode ="Custom" customUserNamePasswordValidatorType 

="SupportClasses.CustomUserNameValidator,SupportClasses"/>
            </serviceCredentials>
            <!-- The following element specifies how we're authorizing based on the client certificates received -->
            <serviceAuthorization serviceAuthorizationManagerType="SupportClasses.AuthorizationManager, SupportClasses"/>
            <serviceMetadata httpsGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
    </serviceBehaviors>
</behaviors>

では、どこに問題があるのでしょうか。さて、その<serviceBehavior>要素を見ますか?ご存じのとおり、この要素はサービスにグローバルに適用されます。つまり、実行時に CustomUserNameValidator と AuthorizationManager の両方が呼び出されます。後者は、クライアントが wsHttpBinding! を使用してサービスを呼び出すと、証明書が存在しないと文句を言います。

ああ!

代替ソリューション

これまでのところ、これらは私が思いついた代替ソリューションです。

代替案 1)別の URL で WCF サービスをホストする別の Windows サービスを作成します。その後、両方のサービスが個別の構成になります。

代替案 2)同じ Windows サービスでホストされる 2 つのサービス実装を作成し、それぞれ独自のバインディングと serviceBehaviour を使用して要素で両方を公開します。

代替案 3)現在の構成を維持し、CustomUserNameValidator と AuthorizationManager を平和的に共存させることが可能かどうかを判断する

この長い投稿で申し訳ありませんが、質問の背景を提供する際には徹底する必要がありました.

質問 1)重要な構成を使用して、WCF を Java クライアントと連携させた人はいますか?

質問 2)選択肢 3 を解決する方法について誰か提案がありますか? (できれば)

質問 3)上記の代替案のうち、推奨するものはどれですか?

質問 4)私が考えていない、あなたが知っている他の選択肢はありますか?

記録として、私は WCF 相互運用性ツールを調べましたが、それがどのように役立つかはよくわかりません。これを読んで相互運用性「ウィザード」を使用して良い結果が得られた場合、

私にお知らせください。

前もって感謝します。

--ノルジー

4

1 に答える 1

0

//services に 2 番目の要素を追加することから始め、新しい @bindingConfiguration 属性と個別の @address 属性を使用して構成します。代替案1、2、または3よりも簡単になると思います。または多分それは選択肢 3 である、私にはわかりません。

Web サービスは、言語、ベンダー、プラットフォーム、およびベンダーに依存しない相互運用を提供するために存在します。WCF と Java は、現実世界のソリューションで毎日相互運用されています。

WCF と Java の相互運用に関するこのシリーズを見たことがありますか?

また、.NET/WCF クライアント メッセージと Java クライアント メッセージの違いを確認できるいくつかの診断ツールを使用するとメリットがあるようです。Fiddler またはその他のスニファー ユーティリティを使用して、ネットワーク上のメッセージを確認します。WCF トレースをオンにして、メッセージを受信した後の WCF の動作を確認します。

于 2011-11-13T05:53:35.747 に答える