WCF 例外 - クライアント証明書が提供されていません。ClientCredentials にクライアント証明書を指定します。
この件に関して私が見つけたもののほとんどを読み、さまざまなオプションを試してみた結果、引っ張る必要がなくなったので、この投稿を行いました。
HTTP トランスポートを使用した TransportWithMessageCredential のセキュリティ モードを持つ、自己ホスト型の WCF サービスで SSL を使用したいと考えています。2 台の開発マシンを使用し、LAN 経由でテストしています。
上記のように、私はこれを示すほぼすべての例を読み、細心の注意を払って従いましたが、何らかの形で証明書にまだ問題があります。
証明書に関する限り、私は多くのことを試しました。
私がしたことの主な趣旨は、 http://msdn.microsoft.com/en-us/library/ff647171.aspxに記載されている内容に従うことでした
基本ガイドとして、http://msdn.microsoft.com/en-us/library/ff648360.aspxの「方法: Windows フォームからの WCF 呼び出しで証明書認証とメッセージ セキュリティを使用する」も使用しまし た。
最初に、物事を検証するために、Http で basicHttpBinding を使用してサービスとクライアントをテストしました。
次に、wsHttpBinding、SSL、および証明書に変更を加えました。
クライアント開発 PC で「サービス参照を追加」すると、次のようなエラーが表示されます。
- ウィンドウタイトル -
セキュリティーアラート
Visual Studio は、サイトのセキュリティ証明書に問題を検出しました。
発行者: RootCATest 発行先: TempCert 証明書の有効期限 ---
企業が発行したセキュリティ証明書が untrust リストにありません。信頼できるかも。
セキュリティ証明書の日付は有効です。
ホスト 'TempCert' のセキュリティ証明書が、表示しようとしているページの名前と一致しません。
- 続行しますか? -
[はい] をクリックして続行し、クライアント コードを実行すると、次のメッセージと共に InvalidOperationException が発生します。
「クライアント証明書が提供されていません。ClientCredentials でクライアント証明書を指定してください。」</p>
サービス構成は次のとおりです。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="CN=TempCert"
storeLocation="LocalMachine"
storeName="My" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="SBSWCFServiceHost.Operations"
behaviorConfiguration="ServiceBehavior">
<endpoint name="wsHttpEndpoint"
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
contract="SBSWCFServiceHost.IOperations" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint name="mexHttpEndpoint"
address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" >
</endpoint>
<host>
<baseAddresses>
<add baseAddress="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
クライアント構成は次のとおりです。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="EndpointBehavior">
<clientCredentials>
<clientCertificate storeLocation="LocalMachine"
storeName="My"
x509FindType="FindByThumbprint"
findValue="e4c87a961f796be6b6cab59c3760e43ffb6e941d"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/"
binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
contract="SBSWCFService.IOperations" name="wsHttpEndpoint">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
以下は、多数の投稿やドキュメントの内容に基づいて、私が実行したタスクの概要です。
サーバー上に自己署名 CA 証明書 (RootCATest という名前) を作成し、ローカル コンピューターの信頼されたルート証明機関の証明書フォルダーに配置しました。
RootCATest 証明書 (TempCert という名前) によって署名された証明書をサーバー上に作成し、ローカル コンピューターの個人証明書フォルダーに配置しました。
TempCert 証明書と秘密鍵をエクスポートしました。
TempCert .cer および .pvk ファイルをクライアント マシンにコピーし、TempCert 証明書をローカル コンピューターの個人証明書フォルダーにインポートしました。
TempCert 証明書の秘密キーへのパスを使用して、サーバー マシンで ICalcs.exe [秘密キーのパス] /grant "NT AUTHORITY\NETWORK SERVICE":R を実行しました。
サーバーマシンで netsh http add sslcert ipport=oooo:8003 certhash=[TempCert thumbprint] appid=[{application id}] を実行
私はこれを機能させることに近づいていると信じています。
アプリが TempCert 証明書に満足していないことは明らかですが、私はこれを解決できず、かなり行き詰まっています。
指定された構成の問題、正しい証明書を配置するために私が従った手順、およびアクセス許可と sslcert エントリを追加するために使用された手順に関する支援をいただければ幸いです。
どうもありがとう。
さらにいくつかの実験を行った後、追加の動作に気付きました。
実行した手順は次のとおりです。
クライアント証明書とサーバー証明書の両方を削除し、....codeproject.com/Articles/36683/9-simple-steps-to-enable-x-509-certificates-on-wcf に従って再作成しました
netsh を使用して新しい sslcert を追加しました。次に、クライアント証明書をサーバーからエクスポートし、クライアント ストアにインポートしました。
新しい証明書情報でサービス app.config を変更し、サービスを開始しました。
クライアント app.config を次のように変更しました。
<endpointBehaviors>
<behavior name="EndpointBehavior">
<clientCredentials>
<clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="WCFClient" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
サービスリファレンスを更新しました。更新手順では、以前と同様にセキュリティ アラートが再度発行されました。
次に、クライアントを実行し、次のエラーを受け取りました。
「クライアント証明書が提供されていません。ClientCredentials でクライアント証明書を指定してください。」
次に、「client = new WCFService.Client();」にブレークポイントを設定します。「クライアント」インスタンスをチェックしました。client.ClientCredentials.ClientCertificate.Certificate の値 = null。
次に、「client = new WCFService.Client();」の後に次のコードを追加しました。
X509Store store = new X509Store("My", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection) store.Certificates;
foreach (X509Certificate2 x509 in collection)
{
if (x509.Thumbprint == "236D7D4AD95753B8F22D3781D61AACB45518E1B5")
{
client.ClientCredentials.ClientCertificate.SetCertificate(
x509.SubjectName.Name, store.Location, StoreName.My);
}
}
このコードの実行後、client.ClientCredentials.ClientCertificate.Certificate に証明書が含まれていました。
次に「client.Open();」を実行すると 、次の内容で例外がスローされます。
基になる接続が閉じられました: SSL/TLS セキュア チャネルの信頼関係を確立できませんでした。検証手順によると、リモート証明書は無効です。権限を持つ SSL/TLS セキュア チャネルの信頼関係を確立できませんでした
ここで何が起こっているのかを知っている人がこれに光を当てることができれば、私は非常に感謝しています.