2009-04-08 14 views
6

Próbuję go uzyskać serwer i klient WCF wzajemnie uwierzytelniać się przy użyciu certyfikatów SSL na poziomie transportu przy użyciu BasicHttpBinding. Oto jak serwer jest coraz stworzył:BasicHttpBinding z uwierzytelnieniem certyfikatu - błąd "zabroniony"?

var soapBinding = new BasicHttpBinding() { Namespace = "http://test.com" }; 
soapBinding.Security.Mode = BasicHttpSecurityMode.Transport; 
soapBinding.Security.Transport.ClientCredentialType = 
    HttpClientCredentialType.Certificate; 
var sh = new ServiceHost(typeof(Service1), uri); 
sh.AddServiceEndpoint(typeof(IService1), soapBinding, ""); 
sh.Credentials.ServiceCertificate.SetCertificate(
    StoreLocation.LocalMachine, StoreName.My, 
    X509FindType.FindBySubjectName, "localhost"); 
sh.Open(); 

Oto klient:

var binding = new BasicHttpBinding(); 
binding.Security.Mode = BasicHttpSecurityMode.Transport; 
var service = new ServiceReference2.Service1Client(binding, 
    new EndpointAddress("https://localhost:801/Service1")); 

service.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.LocalMachine, StoreName.My, 
    X509FindType.FindBySubjectName, "localhost"); 

service.ClientCredentials.ServiceCertificate.Authentication. 
    CertificateValidationMode = 
     System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust; 

service.HelloWorld(); 

Certyfikat dla localhost jest w osobistym, zaufanego głównego i zaufanym pojemników 3rd party. Internet Explorer może połączyć się z hostem i zobaczyć WSDL. Również połączenia SSL działa dobrze z ClientCredentialType = HttpClientCredentialType.None

HelloWorld() nie powiedzie się z:

System.ServiceModel.Security.MessageSecurityException occurred<br/> 
    Message="The HTTP request was forbidden with client authentication 
    scheme 'Anonymous'." 

który jest rethrown wyjątek od: "Zdalny serwer zwrócił błąd:. (403) Zakazane"

Jak można się obejść, zastanawiając się, co dzieje się z wtf?

Odpowiedz

9

Spróbuj dodać ten w kliencie tuż po ustawieniu Security.Mode:

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 
+0

Nie mogę uwierzyć, że to było takie proste, a ja go nie złapać :( – galets

+0

Mam ten sam problem, ale gdzie app.config posiada: <= transportu clientCredentialType "Certificate" proxyCredentialType = "None" realm = ""> w elemencie transportowym :-( – Ronnie

+0

Próbuję rozwiązać podobny problem - po prostu wypróbowałem twój kod, ale "dodaj odniesienie do usługi" nie działało na kliencie . Nie sądzę, żebyś mógł dołączyć całe rozwiązanie? – user1229458

0

Odpowiedź jest już zrobione, ale dla innych:

jeśli używasz standart generowane proxy, który jest skonfigurowany w app.config trzeba ustawić transport ClientCredentialType do Certificate

(być pewien element XML nie jest <message clientCredentialType ... />)

  <binding name="SpoDataServiceSoap"> 
       <security mode="Transport"> 
        <transport clientCredentialType="Certificate"></transport> 
       </security> 
      </binding> 

C#

MyServiceSoapClient client = new MyServiceSoapClient() 
X509Certificate2 cert = CertificateHelper.GetClientCertificate(); 
client.ClientCredentials.ClientCertificate.Certificate = cert; 
Powiązane problemy