クライアントとサーバーの両方で証明書認証を使用して WCF サービスをセットアップしようとしています。私は地獄を通り抜け、考えられるすべてのエラーメッセージをループしています。
ここでの最終的な目的は、証明書を使用して両当事者を認証することです。すべてのクライアントに対して特定の証明書を発行する予定です。これにより、(うまくいけば) それらを区別できるようになります。
これまでのところ、次の構成ファイルがあります。
サーバー構成ファイル
<configuration>
<system.serviceModel>
<services>
<service name="ServiceApiImplementation" behaviorConfiguration="myBehaviour">
<host>
<baseAddresses><add baseAddress="http://localhost:9110/MyService"/></baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="IServiceAPI" bindingName="SOAP12Binding">
<identity>
<certificateReference findValue="ServerCertificate" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/>
</identity>
</endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="SOAP12Binding" receiveTimeout="00:02:00" closeTimeout="00:01:00" openTimeout="00:01:00" sendTimeout="00:01:00">
<security mode="Message">
<message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="myBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="ServerCertificate" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
クライアント構成ファイル
<system.serviceModel>
<client>
<endpoint address="http://localhost:9110/MyService" binding="wsHttpBinding"
bindingConfiguration="SOAP12Binding_IServiceAPI" contract="IServiceAPI"
behaviorConfiguration="behaviour1" name="SOAP12Binding_IServiceAPI">
<identity>
<!-- Value obtained when "Adding a Service Reference in visual studio" -->
<certificate encodedValue="xxxxxxxxxxxxx" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="behaviour1">
<clientCredentials>
<clientCertificate findValue="ClientCertificate" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<defaultCertificate findValue="ServerCertificate" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
<authentication certificateValidationMode="ChainTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="SOAP12Binding_IServiceAPI">
<security mode="Message">
<message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
クライアントとサーバーの両方に rootCA といくつかの証明書を生成し、適切なアクセス許可を与えてストアに配置しました (LocalMachine と CurrentUSer の両方を絶望から解放します)。私の知る限り、このビットは機能しています。
サービスを呼び出すときに問題が発生します。最新のエラーは次のとおりです。
保護されていない、または誤って保護された障害が相手から受信されました。障害コードと詳細については、内部の FaultException を参照してください。
メッセージを処理できませんでした。これは、アクション「http://tempuri.org/IServiceAPI/MyMethod」が正しくないか、メッセージに無効または期限切れのセキュリティ コンテキスト トークンが含まれているか、バインディング間に ismatch があるためである可能性があります。非アクティブのためにサービスがチャネルを中止した場合、セキュリティ コンテキスト トークンは無効になります。サービスがアイドル セッションを途中で中止しないようにするには、サービス エンドポイントのバインディングで受信タイムアウトを早めに増やします。
または(前のエラー)
送信メッセージの ID チェックに失敗しました。期待される ID は 'identity(http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn )' 'http://localhost:9110/MyService' ターゲット エンドポイントの場合。
エラー メッセージは、構成ファイルでの実験によって異なります。現在、クライアントとサーバーの両方が同じマシンで実行されているため、少なくとも、各アプリが rootCA を介して他のアプリを認証することを期待しています。
私は Message Security と wsHttpBinding を使用していることに注意してください。標準の JAVA フレームワークで使用できるサービスを公開することを除いて、大きな制限はありません。
この混乱を整理するのを手伝ってくれる人はいますか?
どんな助けでも大歓迎です
よろしく、