我正在开发使用SSL和证书进行相互身份验证的WCF Web服务的概念验证。带有相互身份验证证书的WCF Web服务在客户端链信任验证上失败
所以,我有两个证书都由有效的证书颁发机构提供(这些是生产证书,而不是开发)。下面是链和证书的商店位置:
服务器证书链
- 发行人的根CA
- 中级1 CA
- 服务器身份验证证书
我不知道这个细节很重要与否:服务器证书是域通配符证书(* .mydomain.com来)
客户端证书链
- 发行人根CA
- 中间体2 CA
- 客户端身份验证证书
发行人根CA是两个证书共同的根CA。
中间体证书不同。
商店位置
发行人的根CA已导入到受信任的根CA在服务器和客户机 中间CA 1 & 2已导入到中间CA服务器和客户端上 颁发者和中间证书只有公钥。
服务器证书已导入到服务器上的个人。这个证书有一个私钥。 服务器证书已导入到客户机上的个人。该证书只有一个公钥。 客户端身份验证证书已导入到服务器和客户端计算机上的个人。这些证书都有私钥。
我创建了一个简单的WCF应用程序项目,托管在IIS 8.5与框架C#4.0中。 我使用在创建项目时默认提供的示例类,我刚刚将其重命名为DemoService.svc。 然后,我创建了客户端(我使用winform应用程序让目标用户有一个图形界面来查看结果)并添加Web服务引用。
然后,我修改了服务配置以建立相互认证。所有通过web.config中完成的:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="demoServiceBehavior">
<serviceAuthorization principalPermissionMode="UseWindowsGroups"></serviceAuthorization>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="*.mydomain.com"/>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" mapClientCertificateToWindowsAccount="true"
trustedStoreLocation="LocalMachine"/>
<certificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"
findValue="myservice.mydomain.com"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="demoServiceBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add service="WcfMutualAuthenticationServiceDemo.DemoService" relativeAddress="DemoService.svc" />
</serviceActivations>
</serviceHostingEnvironment>
<services>
<service name="WcfMutualAuthenticationServiceDemo.DemoService" behaviorConfiguration="demoServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://myservice.mydomain.com/"/>
</baseAddresses>
</host>
<endpoint name="demoServiceEndpoint"
address=""
binding="basicHttpBinding"
bindingConfiguration="demoServiceBinding"
contract="WcfMutualAuthenticationServiceDemo.IDemoService"></endpoint>
</service>
</services>
</system.serviceModel>
我修改了客户端配置来建立相互认证过:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="demoClientBehavior">
<clientCredentials>
<clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"
findValue="myservice.dekra-automotivesolutions.com"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="demoClientBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://myservice.mydomain.com/DemoService.svc"
behaviorConfiguration="demoClientBehavior"
binding="basicHttpBinding"
bindingConfiguration="demoClientBinding"
contract="DemoServiceValidReference.IDemoService"
name="demoServiceEndpoint" />
</client>
</system.serviceModel>
当我打电话通过客户端的Web服务,它返回一个例外:
System.ServiceModel.Security.SecurityNegotiationException:无法 建立安全通道的SSL/TLS权威 'myservice.mydomain.com'。 ---> System.Net.WebException:请求已中止:无法创建 SSL/TLS安全通道。在System.Net.HttpWebRequest.GetResponse() 在System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度 超时)---内部异常堆栈跟踪的结尾---
经过调查,我在服务器的事件查看器中找到一个条目:
处理异常。异常详细信息: System.IdentityModel.Tokens.SecurityTokenValidationException: X.509证书CN = myservice.mydomain链构建失败。使用的 证书具有无法验证的信任链。 替换证书或更改certificateValidationMode。一个 认证链处理正确,但其中一个证书不受策略提供程序的信任。
在 System.IdentityModel.Selectors.X509CertificateChain.Build(X509Certificate2 证书)在 System.IdentityModel.Selectors.X509CertificateValidator.ChainTrustValidator.Validate(X509Certificate2 证书)在 System.IdentityModel.Selectors.X509SecurityTokenAuthenticator.ValidateTokenCore( SecurityToken 令牌)在 System.IdentityModel.Selectors.SecurityTokenAuthenticator.ValidateToken(SecurityToken 令牌)在 System.ServiceModel.Channels.HttpsChannelListener
1.CreateSecurityProperty(X509Certificate2 certificate, WindowsIdentity identity, String authType) at System.ServiceModel.Channels.HttpsChannelListener
1.ProcessAuthentication(IHttpAuthenticationContext authenticationCont EXT)在 System.ServiceModel.Activation.HostedHttpContext.OnProcessAuthentication() 在 System.ServiceModel.Channels.HttpRequestContext.ProcessAuthentication() 在 System.ServiceModel.Channels.HttpChannelListener1.HttpContextReceivedAsyncResult
1.Authenticate() 在 系统。 ServiceModel.Channels.HttpChannelListener1.HttpContextReceivedAsyncResult
1。ProcessHttpContextAsync()
关于这个例外,我发现问题是在客户端身份验证证书的链验证,但我不知道为什么。 在这一点上,我卡住了! 我不知道我的证书有什么问题,我不知道如何找到解决方案。
我真的希望有人能帮我解决这个问题。
编辑: 我们已经与另一客户端证书测试证书链是在服务器和客户端证书一样,它不会改变任何东西。
感谢您自己分享答案。我可以问你一个问题吗? WSDL有非对称绑定元素? –