2012-01-10 14 views
10

C#で証明書認証を使用してServiceClientをプログラムでセットアップするにはどうすればよいですか?
そして、私は.configを使いたくありません。プログラムで証明書認証を使用してWCFサービスクライアントを構成する

 using(var srv = GetServiceInstance()) 
     { 
      srv.DoStuff() 
     } 

     private TheServiceClient GetServiceInstance() 
     { 
      var service = new TheServiceClient(CreateWsHttpBinding(), CreateEndpointAdress()); 
      return service; 
     } 
     private static WSHttpBinding CreateWsHttpBinding() 
     { 
     var wsHttpBinding = new WSHttpBinding(); 
     wsHttpBinding.Security.Mode = SecurityMode.Message; 

     wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; 
     wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None; 
     wsHttpBinding.Security.Transport.Realm = ""; 
     wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; 

     wsHttpBinding.Security.Message.NegotiateServiceCredential = true; 
     wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; 

     wsHttpBinding.Name = "Bindingname"; 
     wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(1); 
     wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(1); 
     wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10); 
     wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(1); 
     wsHttpBinding.BypassProxyOnLocal = false; 
     wsHttpBinding.TransactionFlow = false; 
     wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; 
     wsHttpBinding.MaxBufferPoolSize = 524288; 
     wsHttpBinding.MaxReceivedMessageSize = 65536; 
     wsHttpBinding.MessageEncoding = WSMessageEncoding.Text; 
     wsHttpBinding.TextEncoding = Encoding.UTF8; 
     wsHttpBinding.UseDefaultWebProxy = true; 
     wsHttpBinding.AllowCookies = false; 

     wsHttpBinding.ReaderQuotas.MaxDepth = 32; 
     wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384; 
     wsHttpBinding.ReaderQuotas.MaxStringContentLength = 8192; 
     wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096; 
     wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384; 

     wsHttpBinding.ReliableSession.Ordered = true; 
     wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10); 
     wsHttpBinding.ReliableSession.Enabled = false; 

     return wsHttpBinding; 
    } 
     private static EndpointAddress CreateEndpointAdress() 
     { 
      var store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser); 
      store.Open(OpenFlags.ReadOnly); 
      var cert = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=Certname", false)[0]; 
      store.Close(); 

     var endpointIdentity = EndpointIdentity.CreateX509CertificateIdentity(cert); 
     var endpoint = new EndpointAddress(new Uri("ServiceUri"), endpointIdentity); 

     return endpoint; 
    } 

これは私がこれまで行ってきたことです! これを使用すると、次のエラーが返されます。

クライアント証明書は提供されていません。 ClientCredentialsにクライアント証明書 を指定します。

誰でも知っていますか?優しい、私はこれに新しいです!

答えて

9

他の回答のコメントで発見されたように、service.ClientCredentials.ClientCertificate.Certificateを直接設定する必要があります。

0

は、その証明書がマシンアカウントに表示されているかどうかを確認する必要があるかもしれません - あなたは、以下の点にデバッグしてきたと仮定すると:?

var cert = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=Certname", false)[0];

と、それを見つけることができないと言っていますか

+0

certが見つかり、設定されています。 service.ClientCredentials.ClientCertificate.Certificate is null – espvar

+0

'service.ClientCredentials.ClientCertificate.Certificate'を直接設定するつもりはありませんか?それは読み書き可能であると文書化されています。 'ClientCredentials.UserName.UserName'と' ClientCredentials.UserName.Password'の直前にあります。私は 'EndpointIdentity'はクライアントではなくサービスエンドポイントのものだと思います。 – shambulator

+0

それも私が考え出したものです。私が 'service.ClientCredentials.ClientCertificate.Certificate = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName、" CN = CertName "、false)[0];を置くと、GetServiceInstanceメソッドでそれが機能しました。私はまた、EndpointIdentityを 'var endpointIdentity = EndpointIdentity.CreateDnsIdentity(" DnsIdentity ");' – espvar

0

契約の説明が不足していると思います。ここでは、それを行う方法の小さな例です。さらに問題がある場合、私は完全な作業コードを持っています。私はあなたを助ける。

ContractDescription契約= ContractDescription.GetContract(typeof(IEvalService)、typeof(EvalServiceClient));

プロキシを開く前にクライアントで初期化する必要があります。それが動作することを願っています。

楽しい

関連する問題