2013-08-15 3 views
2

У меня возникают проблемы с получением клиентом WCF для подключения к серверу, для которого требуется сертификат клиента, а также имя пользователя/пароль.Сертификат клиента WCF и учетные данные UserName запрещены

Я проверил, что, используя только сертификат клиента работ с использованием этого:

 var binding = new WSHttpBinding(SecurityMode.Transport); 
     binding.Security.Transport = new HttpTransportSecurity(); 
     binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 

     var ea = new EndpointAddress(EndpointUrl); 

     using (var p = new ServiceReference1.AAAClient(binding, ea)) 
     { 
      try 
      { 
       p.ClientCredentials.ClientCertificate.SetCertificate(
         System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, 
         System.Security.Cryptography.X509Certificates.StoreName.My, 
         System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, 
         CertificateSubject); 

       var x = p.RequiresClientCertificateOnly(); 
       Console.WriteLine("Status: " + x.status); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 

      Console.WriteLine(); 
     } 

Следующим логическим шагом было добавление частей имя пользователя/пароль, но он возвращается с 403 несанкционированным. Я знаю, что учетные данные и сертификат действительны, поскольку я использовал скрипач посередине, чтобы предоставить сертификат клиента и имя пользователя/пароль, и он отлично работает, просто при использовании всего через WCF он, похоже, не работает, или используйте отправку как клиентского сертификата и имя пользователя/пароль.

код пытается использовать как ниже (пробовал с WsHttpBinding и BasicHttpBinding - тот же результат для обоих):

 var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential); 
     binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 
     binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; 

     var ea = new EndpointAddress(EndpointUrl); 

     using (var p = new ServiceReference1.PingPortTypeClient(binding, ea)) 
     { 
      try 
      { 
       p.ClientCredentials.ClientCertificate.SetCertificate(
         System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, 
         System.Security.Cryptography.X509Certificates.StoreName.My, 
         System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, 
         CertificateSubject); 

       p.ClientCredentials.UserName.UserName = Username; 
       p.ClientCredentials.UserName.Password = Password; 

       var x = p.pingDatabase(); 
       Console.WriteLine("Status: " + x.status); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 

      Console.WriteLine(); 

Когда я Гото URL-адрес непосредственно в браузере - я получаю ошибку:

HTTP Error 403.7 - Forbidden The page you are attempting to access requires your browser to have a Secure Sockets Layer (SSL) client certificate that the Web server recognizes.

Это означает, что сертификат не отправляется во втором примере выше, поскольку он принимает ту же ошибку (403).

Может ли кто-нибудь помочь мне с конфигурацией WCF для предоставления сертификата клиента и имени пользователя/пароля? Я трал сеть, и «подобные вопросы» здесь ничуть не помогли. Сейчас это очень расстраивает - чего мне не хватает?

+0

может у вас, пожалуйста, покажите мне web.config? – rauts

+0

Вы также создаете службу WCF или используете ее только. Если вы создаете службу WCF, тогда у вас нет удостоверения клиента и аутентификации имени пользователя и пароля на той же конечной точке. создайте две разные конечные точки с каждым режимом аутентификации (Разделение основных проблем) :) – rauts

+0

Хорошо, я думаю, что вижу проблему, но я не вижу легкого исправления. У вас работает SSL. На основе кода вы используете SSL для шифрования своего сообщения, но вы также используете шифрование на уровне сообщений, чтобы сохранить учетные данные пользователя аутентификации клиента, которые вы передаете на хост. ПОЧЕМУ У вас используются идентификаторы пользователя/идентификатора и удостоверения клиента для аутентификации на хост? Я некоторое время работал с WCF, шифрованием и учетными данными клиента, и я никогда не видел, чтобы кто-то пытался использовать оба. – Brian

ответ

5

Вы должны использовать пользовательскую привязку, если хотите как имя пользователя (уровень сообщения), так и сертификат (уровень транспорта). Например:

 <customBinding> 
      <binding name="NewBinding0"> 
       <textMessageEncoding messageVersion="Default" /> 
       <security authenticationMode="UserNameOverTransport"> 
        <secureConversationBootstrap /> 
       </security> 
       <httpsTransport requireClientCertificate="true" /> 
      </binding> 
     </customBinding> 

Значение messageVersion зависит от того, хотите ли вы использовать WSHttp или BasicHttp. В настоящее время я установил его в «По умолчанию», который является WSHttp, для Basic установите его в «Soap11».

+0

Большое вам спасибо, что получил меня на 95% и теперь все работает. Было на удивление трудно найти такие примеры, как это! – Rosstified

+0

@RM Можете ли вы прокомментировать, как вы сделали это на 100%? Потому что ваш вопрос почти идентично отражает то, что я пытаюсь сделать ... вплоть до кода. Кроме того, эта привязка распространяется на службу WCF, а также на клиента? – Bensonius

+0

Кроме того, кроме этого связывания, вам нужно было изменить свой код или другие значения WCF web.config? – Bensonius

Смежные вопросы