サーバー上で使用したい WCF 対応の Windows サービスがあります。これらの証明書を使用して通信を保護できるように、サーバーとクライアントの両方のストアに適切な証明書が必要です。
私は WCF 構成の経験があまりないので、さまざまな設定や要素がたくさんある悪夢であることが判明しました。
私の現在のクライアント構成の関連部分は次のとおりです (使用しなければならないバージョンの IE では、コードの書式設定が適切に機能しないようです。うまくいけば、後で自宅で修正します)。
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding">
<security mode="Message">
<message
clientCredentialType="Certificate"
negotiateServiceCredential="false"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="wsHttpCertificateBehavior">
<clientCredentials>
<clientCertificate
findValue="MyCert"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication
certificateValidationMode="PeerOrChainTrust"
revocationMode="NoCheck"
trustedStoreLocation="LocalMachine"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint
address="http://someserver:1234/wcf/service/"
behaviorConfiguration="wsHttpCertificateBehavior"
binding="wsHttpBinding"
contract="SomeNamespace.ISomeInterface"
name="wsHttpEndpoint">
<identity>
<servicePrincipalName value="what to put here?"/>
<certificateReference
findValue="MyCert"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
サーバー構成は次のようになります。
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true"/>
</system.web>
<system.serviceModel>
<services>
<service
name="Os2CentralWcf.CentralAdUserManager"
behaviorConfiguration="wsHttpCertificateBehavior">
<host>
<baseAddresses>
<add baseAddress="http://someserver:1234/wcf/service/"/>
</baseAddresses>
</host>
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
contract="SomeNamespace.ISomeInterface"
name="wsHttpEndpoint">
<identity>
<dns value="MyCert"/>
</identity>
</endpoint>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
name="mexEndpoint"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="Message">
<message
establishSecurityContext="false"
negotiateServiceCredential="false"
clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="wsHttpCertificateBehavior">
<serviceMetadata
httpGetEnabled="true"
httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization principalPermissionMode="None"/>
<serviceCredentials>
<clientCertificate>
<authentication
certificateValidationMode="PeerOrChainTrust"
revocationMode="NoCheck"/>
</clientCertificate>
<serviceCertificate
findValue="MyCert"
storeLocation="LocalMachine"
x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
servicePrincipalName
クライアントの構成でa を指定しないと、次のようになります。
System.ServiceModel.Security.MessageSecurityException: Client cannot determine the Service Principal Name based on the identity in the target address 'http://someserver:1234/wcf/service' for the purpose of SspiNegotiation/Kerberos. The target address identity must be a UPN identity (like acmedomain\alice) or SPN identity (like host/bobs-machine).
そのような要素を追加しようとすると (たとえば<servicePrincipalName value=HOST/someserver:1234"/>
、以下の投稿で提案されているように)、最終的には次のようになります。
System.ServiceModel.Security.SecurityNegotiationException: Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.
今、私の実際の質問は、identity
サブ要素をまったく使用する必要があるかどうかです(エラーメッセージはこれを示しているようですが、理由がわかりません)。また、要素に何を入れるか、servicePrincipalName を指定する方法に関する詳細なドキュメントも見つかりませんdns
でした (本当に必要な場合 -この投稿もあまり役に立ちませんでした)。
クライアントとサーバー (サービス) の両方を Visual Studio 2010 内でローカルに実行すると、正常に動作します。十分な情報を提供できれば幸いです。それ以外の場合は、お気軽にお問い合わせください。残念ながら、WCF の構成を深く掘り下げてみると、かなり混乱しているようです...
アップデート
現時点では、basicHttpBinding を使用して、両方の当事者が相互に通信できるようにすることで、ローカルでもサーバーでも問題なく動作します。