我正在开发一个基于供应商实现的 WCF 服务,以从他们那里接收数据。我有一个使用单向 SSL 的服务的工作版本,客户端使用我们的服务器证书。由于最近对他们的实现进行了更改,我现在需要使用证书而不是用户名和密码来验证他们的客户端。
他们用 Java 开发,我无法控制客户端或他们生成证书的方式。它们不支持 WSHttpBinding,所以我必须使用 BasicHttpBinding。他们的证书是自签名的,很遗憾在生产中也是如此。我尝试使用 Transport 来保证安全性,根据我们的服务器管理员的说法,他们的证书已正确安装在我们的服务器上(我无权访问我们的 IIS 服务器)。我相信 IIS 存在证书问题,因为它是自签名的,所以我放弃了该实现。
经过大量研究后,我确定只有通过从OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets[0]
. 这是我的第一个 WCF 服务,所以我相信我已经正确设置了它,但是在从我的 WCF 测试客户端进行测试时出现以下错误:The private key is not present in the X.509 certificate
. 当我从他们的客户那里得到供应商测试时,他们得到了An error occurred when verifying security for the message.
我有什么配置不正确吗?是否支持此实现?
服务 Web.Config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="FileReceiverServiceBehavior">
<useRequestHeadersForMetadataAddress/>
<serviceMetadata httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="FileReceiverServiceBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate"/>
</security>
<readerQuotas maxStringContentLength="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="FileReceiverServiceBehavior" name="FileReceiverService.FileReceiverService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="FileReceiverServiceBinding" contract="FileReceiverServiceSoap" bindingNamespace="http://www.openuri.org/" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
</configuration>
我的 WCF 测试客户端配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="test">
<clientCredentials>
<clientCertificate findValue="Users"
x509FindType="FindBySubjectName"
storeLocation="LocalMachine"
storeName="My"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_FileReceiverServiceSoap" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://mydomain.com/vendor/FileReceiverService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_FileReceiverServiceSoap"
contract="ServiceReference1.FileReceiverServiceSoap" name="BasicHttpBinding_FileReceiverServiceSoap" behaviorConfiguration="test" />
</client>
</system.serviceModel>
</configuration>
更新:
供应商向我发送了正确的证书。它是由商业 CA 颁发的有效证书。当我在本地查看证书时,我可以看到到受信任根的链,并且状态显示为“OK”。
如果我使用security mode="Transport"
并transport clientCredentialType="Certificate"
得到:HTTP 请求被客户端身份验证方案“匿名”禁止
如果我使用security mode="TransportWithMessageCredential"
并message clientCredentialType="Certificate"
得到: X.509 证书中不存在私钥。
我想我可能需要严格使用传输,以便它可以与 Java 客户端互操作,所以我专注于“客户端身份验证方案‘匿名’禁止 HTTP 请求”错误。这是 IIS 设置的问题,还是只是在证书到达服务器时无法正确验证证书?证书在受信任的人中,我没有尝试任何客户端,certificateValidationMode
但也和. 任何帮助将不胜感激。PeerTrust
ChainTrust
PeerOrChainTrust
更新2:
我专注于让它与我的原始服务器配置的以下更改以及与我的测试客户端的匹配更改一起工作:
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
我仍然得到:客户端身份验证方案 'Anonymous' 禁止 HTTP 请求。我在这里找到了一个解释,基本上可以确认客户端证书无法被服务器验证。我如何让我们的服务器管理员在 IIS 中配置此应用程序并安装证书以使其正常工作?