セルフホステッドWCF サービスとクライアント アプリ (今のところコマンド プロンプト) の間で相互 SSL のデモをセットアップしようとしています。最後に、着信接続に証明書を使用するサーバーと、それぞれを一意に識別するために使用できる個別の証明書を持つ複数のクライアントとの間にトランスポート セキュリティ(メッセージ セキュリティではない) があるソリューションにたどり着こうとしています。クライアント。
私はこれに対して多くの異なるアプローチを試みましたが、どれもうまくいきませんでした (私がやろうとしていたことの正確な例を見つけることができませんでした)。近づいていると思うたびに、サービスを呼び出そうとすると、クライアントで例外が発生します。私が遭遇した最も一般的な例外は次のとおりです。
“The HTTP request was forbidden with client authentication scheme 'Anonymous'.”
Inner exception: "The remote server returned an error: (403) Forbidden."
上記のシナリオで相互SSLをセットアップする方法について、私が間違っていた可能性があること、またはおそらくより良いウォークスルーについて考えている人はいますか?
完全な開示 - 現在、私はクライアントとサーバーの両方を同じコンピューターで実行しています。それが重要かどうかはわかりません。
以下の構成スニペット
サービスとクライアントのコードは比較的単純なので、うまく機能させることができたと確信しています。アプリの構成 (具体的にはバインディングと動作) と証明書は「より興味深い」ので、私はそこに自信がありません。
証明書の作成方法 (実際のコマンドは逐語的に)
makecert -pe -n "CN=SelfSignedCA" -ss Root -sr LocalMachine -a sha1 -sky signature -r -sv "SelfSignedCA.cer" "SelfSignedCA.pvk"
makecert -pe -n "CN=system" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "SelfSignedCA" -is Root -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 Service.cer
makecert -pe -n "CN=client1" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "SelfSignedCA" -is Root -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 Client1.cer
証明書をポートに関連付ける (実際のコマンドは逐語的に)
netsh http add urlacl url=https://+:44355/MyService/ user=EVERYONE
サーバー設定
バインディング:
<wsHttpBinding>
<binding name="CustomBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
動作:
<serviceBehaviors>
<behavior name="">
<!--
<serviceCredentials>
<serviceCertificate
findValue="system"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"/>
</serviceCredentials>
-->
<serviceAuthorization
serviceAuthorizationManagerType=
"ClientAuthorization.ClientCertificateAuthorizationManager, Simulator.Service.SideA" />
</behavior>
</serviceBehaviors>
クライアント
バインディング:
<wsHttpBinding>
<binding name="CustomBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
行動
<endpointBehaviors>
<behavior name="ChannelManagerBehavior">
<clientCredentials>
<clientCertificate findValue="client1"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
<!--
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
-->
</clientCredentials>
</behavior>
</endpointBehaviors>
アップデート
そのため、デフォルトの動作をオーバーライドし、提示された資格情報に関係なく常に許可するために、カスタムのユーザー名とパスワードのバリデーターをサーバーに追加しました (ここでも、ユーザー名/パスワードの検証は本当に必要ありません)。 このバリデーターが呼び出されることはありません。 クライアントは引き続き「認証スキーム「匿名」」を取得します。例外。
サービス動作の更新
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType=
"Service.ClientAuthorization.ClientUserNamePasswordValidatorManager, Service.SideA" />
</serviceCredentials>