我正在使用SSL和证书进行相互身份验证的WCF Web服务的概念验证。
因此,我有2个证书都由有效的证书颁发机构提供(这些是生产证书,而不是开发证书)。以下是证书的链和商店位置:
服务器证书链
- 颁发者根CA.
- 中级1 CA.
- 服务器身份验证证书
我不知道这个细节是否重要:服务器证书是域的通配符证书(* .mydomain.com )
客户证书链
- 颁发者根CA.
- 中级2 CA.
- 客户端身份验证证书
颁发者根CA是两个证书的通用根CA.
中间体证书是不同的。
商店位置
颁发者根CA已导入服务器和客户端计算机上的受信任的根CA 中间CA 1&已在服务器和客户端上将2导入到 Intermediate CA 中 发行人和中间人证书只有公钥。
服务器证书已导入服务器计算机上的 Personal 。此证书具有私钥。 服务器证书已导入客户端计算机上的 Personal 。此证书仅具有公钥。 客户端身份验证证书已导入服务器和客户端计算机上的 Personal 。这些证书都有私钥。
我使用框架C#4.0在IIS 8.5中创建了一个简单的WCF应用程序项目。 我在项目创建时使用默认提供的示例类,我刚将其重命名为 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'。 ---&GT; System.Net.WebException:请求已中止:无法创建 SSL / TLS安全通道。在System.Net.HttpWebRequest.GetResponse() at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan) 超时)---内部异常堆栈跟踪结束---
经过调查,我在服务器的事件查看器中找到了一个条目:
处理异常。例外细节: System.IdentityModel.Tokens.SecurityTokenValidationException:The X.509证书CN = myservice.mydomain链构建失败。该 使用的证书具有无法验证的信任链。 替换证书或更改certificateValidationMode。一个 认证链处理正确,但CA之一 策略提供者不信任证书。
在 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 authenticationContext)at System.ServiceModel.Activation.HostedHttpContext.OnProcessAuthentication() 在 System.ServiceModel.Channels.HttpRequestContext.ProcessAuthentication() 在 System.ServiceModel.Channels.HttpChannelListener1.HttpContextReceivedAsyncResult
1.Authenticate() 在 System.ServiceModel.Channels.HttpChannelListener1.HttpContextReceivedAsyncResult
1.ProcessHttpContextAsync()
关于这个例外,我发现问题出在客户端身份验证证书的链验证上,但我不知道为什么。 此时,我被困住了! 我不知道我的证书有什么问题,我不知道如何找到解决方案。
我真的希望有人可以帮我解决这个问题。
修改: 我们已经使用另一个客户端证书进行测试,认证链在服务器和客户端证书上是相同的,它不会改变任何内容。
答案 0 :(得分:1)
今天发现了解决方案:客户端和服务器上的配置正常。 这是对IIS服务器证书映射的错误配置,未配置但未启用功能。