2012-01-10 25 views
10

Jak skonfigurować program ServiceClient przy użyciu uwierzytelniania certyfikatów programowo w języku C#?
I nie chcę używać .config.Konfiguruj klienta usługi WCF z uwierzytelnianiem certyfikatów programowo

 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; 
    } 

To jest to, co mam do tej pory! Korzystanie z tej funkcji powoduje zwrócenie błędu z informacją:

Certyfikat klienta nie jest dostarczany. Określ certyfikat klienta w ClientCredentials.

Ktoś ma pomysł? Bądź łagodny, jestem nowy w tym!

Odpowiedz

9

Jak odkryto w komentarzach do drugiej odpowiedzi, należy bezpośrednio ustawić service.ClientCredentials.ClientCertificate.Certificate.

0

może trzeba sprawdzić, czy certyfikat jest widoczny w rachunku maszynowego - Zakładając, że debugowany do następującej kwestii:

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

i to mówiąc, że nie może go znaleźć?

+0

Znaleziono certyfikat i ustaw. service.ClientCredentials.ClientCertificate.Certificate ma wartość null – espvar

+0

Nie należy ustawiać bezpośrednio 'service.ClientCredentials.ClientCertificate.Certificate'? Jest to dokumentowane jako odczyt-zapis, a dla innych form uwierzytelniania klienta ustawiłem np. 'ClientCredentials.UserName.UserName' i' ClientCredentials.UserName.Password' bezpośrednio przed. Myślę, że rzeczy 'EndpointIdentity' dotyczą punktów końcowych usługi, a nie klientów. – shambulator

+0

To też wymyśliłem. Kiedy umieszczam 'service.ClientCredentials.ClientCertificate.Certificate = store.Certificates.Find (X509FindType.FindBySubjectDistinguishedName," CN = CertName ", false) [0];' W metodzie GetServiceInstance zadziałało. Musiałem również zachować EndpointIdentity, gdzie dodałem 'var endpointIdentity = EndpointIdentity.CreateDnsIdentity (" DnsIdentity ");' – espvar

0

Myślę, że brakuje Ci opisu zamówienia. Oto mały przykład, jak to zrobić. Jeśli masz kolejny problem, mam pełny działający kod. Pomogę Ci.

ContractDescription Contract = ContractDescription.GetContract (typeof (IEvalService), typeof (EvalServiceClient));

Musisz zainicjować z klientem przed otwarciem proxy. Mam nadzieję, że to zadziała.

Miłej zabawy