2012-11-26 31 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