2012-11-26 96 views
0

我試圖使用自簽名證書來執行WCF。我找到了一些解決方案,但他們需要客戶端在連接之前知道clinet證書。 我想使客戶端作爲瀏覽器(當瀏覽器使用Web服務器證書時)。 我的意思是瀏覽器在連接之前不知道web服務器的證書,它可以從web服務器獲取它。 我的服務器的web.config:只有服務器證書的WCF https

<system.serviceModel> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" /> 
    <services> 
     <service behaviorConfiguration="security" name="WebApplicationExchange.UKService"> 
     <endpoint address="" binding="basicHttpBinding" bindingConfiguration="security" contract="WebApplicationExchange.IUKService"> 
      <identity> 
      <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="https://localhost/UKService/UKService.svc" /> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="security"> 
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> 
      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ServiceAuthorization.PasswordValidator,ServiceAuthorization" /> 
      <windowsAuthentication allowAnonymousLogons="false" /> 
      </serviceCredentials> 
      <serviceAuthorization principalPermissionMode="Custom"> 
      <authorizationPolicies> 
       <add policyType="ServiceAuthorization.AuthorizationPolicy,ServiceAuthorization" /> 
      </authorizationPolicies> 
      </serviceAuthorization> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="security"> 
      <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="Basic" /> 
      </security> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    </system.serviceModel> 

它正常工作與網絡瀏覽器。

但客戶端顯示錯誤: 無法建立具有權限「localhost:56389」的安全通道SSL/TLS的信任連接。 客戶端代碼:

System.ServiceModel.EndpointAddress eaSecurity = new System.ServiceModel.EndpointAddress("https://localhost:56389/UKService.svc"); 
       var binding = new System.ServiceModel.BasicHttpBinding(); 
       binding.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.TransportWithMessageCredential; 
       binding.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.None; 
       binding.Security.Message.ClientCredentialType = System.ServiceModel.BasicHttpMessageCredentialType.UserName; 


       var securityFactory = new System.ServiceModel.ChannelFactory<ServiceReference1.IUKService>(binding, eaSecurity); 
       securityFactory.Credentials.UserName.UserName = "test"; 
       securityFactory.Credentials.UserName.Password = "test"; 
       myService = securityFactory.CreateChannel(); 

任何想法如何解決這個問題?

UPDATE: 我看的更深一些錯誤的堆棧,並找到如下: System.Security.Authentication.AuthenticationException:遠程證書根據認證的結果是無效的。 我試過這個代碼:

ClientCredentials cc = securityFactory.Endpoint.Behaviors.Find<ClientCredentials>(); 

       cc.UserName.UserName = "test"; 
       cc.UserName.Password = "test"; 

       cc.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; 

但它沒有幫助。

+0

瀏覽器都具有人類手動驗證證書。那是你想要做什麼? –

+0

不完全,我的意思是瀏覽器在連接之前不知道web服務器的證書,它可以從web服務器獲取它。 – Yury

+0

沒問題,但這隻有在使用瀏覽器的人已經擁有足夠的信息來驗證證書時纔有用。你打算使用人工干預嗎?或者您是否已經有足夠的信息來驗證證書? –

回答

1

我解決這個問題是這樣的:

System.Net.ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(RemoteCertValidateCallback); 
public static bool RemoteCertValidateCallback(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error) 
     { 
      return true; 
     } 
0

問題是您的證書不被客戶端信任。這與客戶端證書或從瀏覽器下載證書無關。

爲了使服務器證書由TE客戶所接受,你需要:

  • 購買的證書來自受信任的證書頒發機構
  • 添加證書(或其根)到客戶端機器的證書存儲區或
  • 禁用證書驗證。
+0

禁用證書驗證 - 它適合我。我寫了以下代碼:ClientCredentials cc = securityFactory.Endpoint.Behaviors.Find (); cc.UserName.UserName =「test」; cc.UserName.Password =「test」; cc.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; – Yury

+0

但這沒有幫助。錯誤是一樣的 – Yury