私は WCF とそのすべての (複雑な) セキュリティ オプションを理解しようとしています。localhost で wsHttpBinding を使用して Wcf Web サービスを開発しました。いくつかのクライアントに配布するコンソール アプリケーションを作成しています。各クライアントには、自分のデータベースに対して検証する独自のユーザー名とパスワードがあります。そのために、codebetter.com の次のチュートリアルに従いました。あなたに言わないこと/
- 自己署名証明書を取得し、アクセス許可を付与しました
- サーバーとクライアントをすべてセットアップし、localhost から localhost で完全に実行しました。
質問1:
VS2010 の [サービスの追加] ダイアログを使用して svc サービスを追加すると、app.config に次のタグが追加されました。
<certificate encodedValue="AwA<...>" />
学習目的で、その値を数回変更しましたが、効果はありませんでした。それは完璧に機能し続けました。Fiddler を使用して、暗号化された通信を確認します。
質問 2: SSL を使用してテスト サーバーにデプロイする
IIS7.5 と SSL が構成されたテスト サーバーに、WCF サービスをホストする Web アプリケーションをデプロイしました。クライアント アプリケーションをテスト サーバーに接続しようとすると、一般的なエラーがスローされました。https:// から http:// に変更すると、機能することがわかりました。Fiddler は、暗号化された値を使用した優れた http 通信を示しました。
しかし、メッセージ レベルの暗号化と共に HTTPS も使用したいと考えています。これは不可能だと思います。セキュリティモードを「TransportWithMessageCredential」に設定するだけで、すべて機能しました。しかし、それを行うと、クライアント上のすべての証明書情報を削除でき、それでも機能します。したがって、トランスポート セキュリティ (のようなもの) がメッセージ セキュリティよりも優先されるという結論を下すことができます。
だから私は正しい結論を出しています:
- https トランスポート セキュリティを取得していませんか? 証明書を使用する (サーバーでは pfx、クライアントでは証明書)
- https トランスポート セキュリティはありますか? 証明書を使用しないでください。SSL で十分です。
私は自分自身を明確にすることを願っています:)。よろしくお願いします。
いくつかの(匿名化された)構成の下:
サーバ
<bindings>
<wsHttpBinding>
<!--The maximum size, in bytes, for a message that is processed by the binding-->
<binding name="Binding1" maxReceivedMessageSize="4194304">
<readerQuotas maxDepth="32" maxStringContentLength="10485760" maxArrayLength="10485760"
maxBytesPerRead="10485760" maxNameTableCharCount="10485760" />
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ApiWcfCustomBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomUserNameValidator, SupplierAPI"/>
<serviceCertificate findValue="xxxxApiv3" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
* クライアント *
var endPoint = new EndpointAddress(new Uri(apiUrl), EndpointIdentity.CreateDnsIdentity(endpointDnsEntity));
var binding = new WSHttpBinding();
//binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.NegotiateServiceCredential = false;
using (var client = new SupplierServiceClient(binding, endPoint))
{
client.ClientCredentials.UserName.UserName = supplierUID;
client.ClientCredentials.UserName.Password = supplierPassword;
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine,
System.Security.Cryptography.X509Certificates.StoreName.My,
System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
endpointDnsEntity);
}