9

WSHttpBindingsを使用して自己ホスト型のWCFサービスを作成し、自分で生成した証明書を使用してメッセージレベルのセキュリティを実装しようとしています。残念ながら、「パッケージに提供されたクレデンシャルが認識されませんでした」という埋め込み例外が(Service Trace Viewerを介して)発生します。

いくつかのメモ:

  1. これは、構成ではなく、コードで実行する必要があります
  2. (サーバー/クライアント)証明書は、デバッグ中にユーザーがアクセスできる秘密鍵を持つローカルマシンストアにある証明書です。
  3. 私はこれから地獄をグーグルで検索し、ここでWCFメッセージベースのセキュリティを設定するための優れたリソースを見つけました

何が欠けているのかわかりません。エンドポイントIDを作成することを除いて、これらのほとんどは簡単に思えます。DnsEndpointIdentitiesを使用するか、証明書ベースのものを使用するか、IDをまったく使用しないかにかかわらず、同じメッセージで失敗します。

誰かが私を正しい方向に向けることができますか?

サーバ側:

var binding = new WSHttpBinding
    {
      Security =
      {
        Mode = SecurityMode.Message,
        Message = 
        {
          ClientCredentialType = MessageCredentialType.Certificate,
          AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256Rsa15
        }
      }
    };

_host = new ServiceHost(this)
{
  Credentials =
  {
    ServiceCertificate =
    {
      Certificate = ServiceCert
    },
    ClientCertificate =
    {
      Certificate = ClientCert,
      Authentication =
      {
        TrustedStoreLocation = StoreLocation.LocalMachine,
        RevocationMode = X509RevocationMode.NoCheck,
        CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust
       }
    }
  }
};
var address = new Uri(string.Format(@"http://serviceaddress"));
var ep = _host.AddServiceEndpoint(typeof (IService), binding, address);
ep.Address = new EndpointAddress(address, EndpointIdentity.CreateX509CertificateIdentity(ServiceCert));
_host.Open();

クライアント側:

var binding = new WSHttpBinding
    {
      Security =
      {
        Mode = SecurityMode.Message,
        Message =
        { 
          ClientCredentialType = MessageCredentialType.Certificate,
          AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256Rsa15
        }
      }
    };
var address = new Uri(@"http://serviceaddress");
var endpoint = new EndpointAddress(address, EndpointIdentity.CreateX509CertificateIdentity(ServerCert));
var channelFactory = new ChannelFactory<IService>(binding, endpoint)
    {
      Credentials =
      {
        ServiceCertificate =
        {
          DefaultCertificate = ServerCert,
          Authentication =
          {
            RevocationMode = X509RevocationMode.NoCheck,
            TrustedStoreLocation = StoreLocation.LocalMachine,
            CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust
          }
        },
        ClientCertificate =
        {
          Certificate = ClientCert
        }
      }
    };
var channel = channelFactory.CreateChannel();
4

1 に答える 1

12

このmsdnの記事は非常に役に立ちました。問題の根本は、次のメッセージセキュリティパラメータをfalseに設定したことだと思います。

httpBinding.Security.Message.NegotiateServiceCredential = false;
httpBinding.Security.Message.EstablishSecurityContext = false;

したがって、サーバー側の全体的なコードは次のようになります。

var httpBinding = new WSHttpBinding(SecurityMode.Message);
httpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
httpBinding.Security.Message.NegotiateServiceCredential = false;
httpBinding.Security.Message.EstablishSecurityContext = false;
var httpUri = new Uri("http://serviceaddress");
_host = new ServiceHost(this, httpUri);
_host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, serverThumbprint);
_host.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
_host.Credentials.ClientCertificate.Authentication.TrustedStoreLocation = StoreLocation.LocalMachine;
_host.AddServiceEndpoint(typeof(IMetaService), httpBinding, httpUri);
_host.Open();

およびクライアント側:

var httpBinding = new WSHttpBinding(SecurityMode.Message);
httpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
httpBinding.Security.Message.NegotiateServiceCredential = false;
httpBinding.Security.Message.EstablishSecurityContext = false;
var httpUri = new Uri("http://serviceaddress");
var httpEndpoint = new EndpointAddress(httpUri, EndpointIdentity.CreateDnsIdentity("name of server cert"));
var newFactory = new ChannelFactory<IMetaService>(httpBinding, httpEndpoint);
newFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "client certificate thumbprint");
newFactory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "server certificate thumbprint");
var channel = newFactory.CreateChannel();
于 2011-05-18T14:26:40.303 に答える