2012-01-10 15 views
10

¿Cómo configuro un cliente de servicio utilizando la autenticación de certificado programáticamente en C#?
Y no quiero usar .config.Configurar el cliente del servicio WCF con autenticación de certificado programáticamente

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

¡Así que esto es lo que tengo hasta ahora! Al usar esto se devuelve un error que dice:

No se proporciona el certificado del cliente. Especifique un certificado de cliente en ClientCredentials.

¿Alguien tiene una idea? Se amable, ¡soy nuevo en esto!

Respuesta

9

Como se descubrió en los comentarios de la otra respuesta, necesita establecer service.ClientCredentials.ClientCertificate.Certificate directamente.

0

puede tener que ver si ese certificado es visible a la cuenta de la máquina - asumiendo que ha depurado a la letra siguiente:

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

y está diciendo que no puede encontrarlo?

+0

se encuentra el certificado. service.ClientCredentials.ClientCertificate.Certificate es nulo – espvar

+0

¿No está destinado a establecer 'service.ClientCredentials.ClientCertificate.Certificate' directamente? Está documentado como de lectura y escritura, y para otras formas de autenticación de cliente, he configurado, p. 'ClientCredentials.UserName.UserName' y' ClientCredentials.UserName.Password' directamente antes. Creo que las cosas de 'EndpointIdentity' son para puntos finales de servicio, no para clientes. – shambulator

+0

Eso es lo que descubrí también. Cuando puse 'service.ClientCredentials.ClientCertificate.Certificate = store.Certificates.Find (X509FindType.FindBySubjectDistinguishedName," CN = CertName ", false) [0];' En el método GetServiceInstance funcionó. También necesitaba mantener EndpointIdentity donde agregué 'var endpointIdentity = EndpointIdentity.CreateDnsIdentity (" DnsIdentity ");' – espvar

0

Creo que se está perdiendo la descripción del contrato. Aquí, hay un pequeño ejemplo de cómo hacerlo. Si tienes más problemas, tengo un código de trabajo completo. Te ayudaré.

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

Debe inicializar con el cliente antes de abrir el proxy. Espero que funcione

se divierten

Cuestiones relacionadas