2013-01-11 3 views
2

WCF 예외 - 클라이언트 인증서가 제공되지 않습니다. ClientCredentials에 클라이언트 인증서를 지정하십시오.WCF 예외 - 클라이언트 인증서가 제공되지 않습니다.

내가이 주제에서 찾을 수 있었던 대부분의 것을 읽고 많은 다른 옵션을 시도한 후에 나는 더 이상 머리카락을 끌어 내지 못한다는 것을 알게되었다.

보안 모드를 HTTP 전송과 함께 TransportWithMessageCredential로 설정하여 자체 호스팅 WCF 서비스에서 SSL을 사용하고자합니다. 나는 2 dev의 기계를 사용하고 LAN을 통해 테스트하고있다.

위에서 언급했듯이, 나는 이것을 보여주는 모든 예를 읽고 꼼꼼하게 따라 왔지만 여전히 인증서에 문제가 있습니다.

인증서에 관한 한 여러 가지를 시도했습니다. A와 http://msdn.microsoft.com/en-us/library/ff648360.aspx 에서 "WCF에서 사용 인증서 인증 및 메시지 보안은 윈도우 폼에서 호출 방법"

내가 무슨 짓을했는지의 주요 JIST 내가 사용할 http://msdn.microsoft.com/en-us/library/ff647171.aspx

에 제시되어있다 팔로우했다 기본 가이드.

먼저 서비스를 확인하고 HTTP를 통해 basicHttpBinding을 사용하여 클라이언트를 테스트했습니다.

그런 다음 wsHttpBinding, SSL 및 인증서를 변경했습니다. 나는 클라이언트 dev에 PC "서비스 참조 추가"하는 경우 다음과 같이

, 나는 오류가 발생 :

  • 창라는 제목 -

보안 경고

비주얼 스튜디오가 감지 한 사이트의 보안 인증서에 문제가 있습니다.

발급자 : --- TempCert 인증서의 유효

회사에서 발급하는 보안 인증서가 언 트러스트 목록에없는 : 발급 RootCATest . 그것은 신뢰할 수 있습니다.

보안 인증서 날짜가 유효합니다.

호스트 'TempCert'의 보안 인증서가 보려는 페이지의 이름과 일치하지 않습니다.

  • 계속 하시겠습니까? -

계속 진행하려면 "예"를 클릭하고 클라이언트 코드를 실행하면 다음 메시지와 함께 InvalidOperationException이 발생합니다.

"클라이언트 인증서가 제공되지 않습니다. ClientCredentials에 클라이언트 인증서를 지정하십시오."

의 서비스 구성은 다음과 같다 :

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name="ServiceBehavior"> 
        <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> 
        <serviceDebug includeExceptionDetailInFaults="true" /> 
        <serviceCredentials> 
         <serviceCertificate findValue="CN=TempCert" 
              storeLocation="LocalMachine" 
              storeName="My" /> 
        </serviceCredentials> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
     <bindings> 
      <wsHttpBinding> 
      <binding name="wsHttpEndpointBinding"> 
       <security mode="TransportWithMessageCredential"> 
       <message clientCredentialType="Certificate" /> 
       </security> 
      </binding> 
      </wsHttpBinding> 
     </bindings>  
     <services> 
      <service name="SBSWCFServiceHost.Operations" 
        behaviorConfiguration="ServiceBehavior"> 
       <endpoint name="wsHttpEndpoint" 
          address="" 
          binding="wsHttpBinding" 
          bindingConfiguration="wsHttpEndpointBinding" 
          contract="SBSWCFServiceHost.IOperations" > 
        <identity> 
         <dns value="localhost" /> 
        </identity> 
       </endpoint>       
       <endpoint name="mexHttpEndpoint" 
          address="mex" 
          binding="mexHttpsBinding" 
          contract="IMetadataExchange" > 
       </endpoint> 
       <host> 
        <baseAddresses> 
         <add baseAddress="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" /> 
        </baseAddresses> 
       </host> 
      </service> 
     </services> 
    </system.serviceModel> 
</configuration> 

클라이언트 설정은 다음과 같다 : 다음

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <behaviors> 
      <endpointBehaviors> 
       <behavior name="EndpointBehavior"> 
        <clientCredentials> 
         <clientCertificate storeLocation="LocalMachine" 
              storeName="My" 
              x509FindType="FindByThumbprint" 
              findValue="e4c87a961f796be6b6cab59c3760e43ffb6e941d"/> 
        </clientCredentials> 
       </behavior> 
      </endpointBehaviors> 
     </behaviors>  
     <bindings> 
      <wsHttpBinding> 
       <binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" 
        receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" 
        transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
        maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
        allowCookies="false"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <reliableSession ordered="true" inactivityTimeout="00:10:00" 
         enabled="false" /> 
        <security mode="TransportWithMessageCredential"> 
         <transport clientCredentialType="None" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="Certificate" negotiateServiceCredential="true" 
          algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" 
       binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" 
       contract="SBSWCFService.IOperations" name="wsHttpEndpoint"> 
       <identity> 
        <dns value="localhost" /> 
       </identity> 
      </endpoint> 
     </client> 
    </system.serviceModel> 
</configuration> 

수많은의 내용을 기반으로, 내가 수행 한 작업의 요약이다 게시물 및 문서.

  1. 서버 (RootCATest라는 이름의) 자체 서명 CA 인증서를 생성하고 로컬 컴퓨터의 신뢰할 수있는 루트 인증 기관 인증서 폴더에 배치.

  2. 서버의 RootCATest 인증서 (TempCert)가 서명 한 인증서를 만들어 로컬 컴퓨터의 개인 인증서 폴더에 저장합니다.

  3. TempCert 인증서와 개인 키를 내 보냅니다.

  4. TempCert .cer 및 .pvk 파일을 클라이언트 컴퓨터에 복사 한 다음 TempCert 인증서를 로컬 컴퓨터의 개인 인증서 폴더로 가져 왔습니다.

  5. 실행 된 ICalcs.exe [개인 키 경로]/부여 "NT AUTHORITY \ NETWORK SERVICE": R 서버 컴퓨터에서 TempCert 인증서의 개인 키 경로를 사용하십시오.

  6. 처형은 netsh HTTP sslcert ipport = o.o.o.o 추가 : 나는 가까운이 작업을 얻기에 나는 믿는다 서버 시스템

에 8003 certhash = [TempCert 지문] APPID = [{응용 프로그램 ID}]를.

이 앱이 TempCert 인증서에 만족스럽지 않은 것 같지만 아직 해결하지 못했고 꽤 당황 스럽습니다.

주어진 구성의 문제와 관련하여 올바른 인증서를 설치하기 위해 수행 한 단계와 액세스 권한 및 sslcert 항목을 추가하는 단계는 크게 감사하겠습니다.

감사합니다.

추가 실험을 한 후 추가 동작을 발견했습니다.

내가 클라이언트와 서버 인증서를 삭제하고, 에 따라 그들을 다시 .... codeproject.com/Articles/36683/9-simple-steps-to-enable 다음과 같이 촬영

단계는 -x-509-certificates-on-wcf

netsh를 사용하여 새 sslcert를 추가했습니다. 그런 다음 서버에서 클라이언트 인증서를 내 보낸 다음 을 클라이언트 저장소로 가져 왔습니다.

서비스 app.config를 새 인증서 정보로 수정하고 서비스를 시작했습니다.

클라이언트 응용 프로그램을 수정했습니다.다음과 같이 구성하십시오.

<endpointBehaviors> 
    <behavior name="EndpointBehavior"> 
    <clientCredentials> 
     <clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="WCFClient" /> 
     <serviceCertificate> 
     <authentication certificateValidationMode="PeerTrust" /> 
     </serviceCertificate> 
    </clientCredentials> 
    </behavior> 
</endpointBehaviors> 

서비스 참조를 업데이트했습니다. 업데이트 절차에서 이전과 같이 보안 경고가 다시 발행되었습니다.

나는 다음 클라이언트를 실행하고,이 오류 받았다 ". 클라이언트 인증서가 제공되지 ClientCredentials에서 클라이언트 인증서를 지정합니다."

그런 다음 "client = new WCFService.Client();"에 중단 점을 설정합니다. "클라이언트"인스턴스를 확인했습니다. client.ClientCredentials.ClientCertificate.Certificate = null 값입니다.

X509Store store = new X509Store("My", StoreLocation.LocalMachine); 
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 
X509Certificate2Collection collection = (X509Certificate2Collection) store.Certificates; 
foreach (X509Certificate2 x509 in collection) 
{ 
if (x509.Thumbprint == "236D7D4AD95753B8F22D3781D61AACB45518E1B5") 
{ 
    client.ClientCredentials.ClientCertificate.SetCertificate(
     x509.SubjectName.Name, store.Location, StoreName.My); 
} 
} 

이 코드의 실행 후, client.ClientCredentials.ClientCertificate.Certificate 인증서를 포함 :; "클라이언트 = 새로운 WCFService.Client()"

는 그때 이후 코드에 다음을 추가했다.

"client.Open();"을 실행하면 , 다음 내용으로 예외가 발생합니다.

내부 연결이 닫혔습니다 : SSL/TLS 보안 채널에 대한 트러스트 관계를 설정할 수 없습니다. 유효성 검사 절차에 따라 원격 인증서가 유효하지 않습니다. 권한이있는 SSL/TLS 보안 채널에 대한 트러스트 관계를 설정할 수 없습니다.

여기서 일어날 수있는 일에 대해 잘 아는 사람이라면 누구에게이 사실을 알릴 수 있는지 매우 고맙게 생각합니다.

답변

1

마지막 오류 메시지는 서버가 클라이언트에서 클라이언트 인증서를 요청하고 (서버가 요청해야 함) 클라이언트가 인증서를 제공하지만 서버가 클라이언트 인증서가 유효한지 여부를 확인할 수 없음을 나타냅니다 서버 시스템에서 사용 가능한 정보를 기반으로합니다.

자체 발급 인증서 (CA 발급 인증서가 아님)를 사용 중이므로 서버에 클라이언트 인증서 유효성 검사 방법을 알려야합니다. WCF의 기본 인증서 유효성 검사에서 찾을 수 있도록 서버의 My/LocalMachine/신뢰할 수있는 사용자 인증서 저장소에 클라이언트 인증서를 설치하거나 서버에서 사용자 지정 클라이언트 인증서 유효성 검사기를 구현해야 할 수 있습니다. (WebHttpBinding.Credentials.ClientCertificate.Authentication.CertificateValidationModeWebHttpBinding.Credentials.ClientCertificate.Authentication.CustomCertificateValidator을 참조하십시오.)

0

정의한 endpoint 정의에서 사용자가 정의한 behavior을 참조하지 않았습니다. 동일한 코드를 일부 코드를 통해 직접 작성하는 것처럼 보입니다. 구성에서 와이어 링하는 것이 더 간단 할 수 있습니다.

나는 엔드 포인트는 다음과 같이 (이상)보고 기대 ". 클라이언트 인증서가 제공되지 ClientCredentials에서 클라이언트 인증서 지정"

이 솔루션이었다
 <endpoint address="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" 
      binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" 
      contract="SBSWCFService.IOperations" name="wsHttpEndpoint" 
      behaviorConfiguration="EndpointBehavior"> 
      <identity> 
       <dns value="localhost" /> 
      </identity> 
     </endpoint> 

, 나는 오류가 발생되었을 때 .

관련 문제