背景(少し長い):
数年前、私は顧客のために、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 相互運用性ツールを調べましたが、それがどのように役立つかはよくわかりません。これを読んで相互運用性「ウィザード」を使用して良い結果が得られた場合、
私にお知らせください。
前もって感謝します。
--ノルジー