【发布时间】:2010-10-30 02:01:38
【问题描述】:
我一直在尝试让 WCF 安全性为我的项目工作,但运气不佳。我正在尝试创建一个使用 net.tcp 作为绑定的服务,并同时提供消息和传输安全性。消息安全性使用用户名和密码完成,传输安全性(据说!)使用证书完成。
为了我的开发测试,我创建了自己的证书颁发机构并将此证书放在我计算机的受信任存储区 (LocalMachine) 中。然后我创建了两个证书,每个都由我的证书颁发机构签名,一个供服务使用,一个供客户端应用程序使用。我将这两个都放在 LocalMachine 的个人商店 (My) 中。然后,为了测试,我创建了一个未经我的证书颁发机构签名的随机证书(因此不受信任),并将其放在 LocalMachine 的个人存储中。我使用 makecert 创建这些证书。
然后,我将连接到服务的客户端应用程序配置为使用无效的不受信任证书作为其客户端证书。该服务设置为(假设)使用链信任检查客户端证书。但是,此客户端能够连接并成功与服务对话!它应该被拒绝,因为它的证书不受信任!
我不知道是什么导致了这种行为,所以我将问题提交给你们,看看你们是怎么做的。这是我的 WCF 配置:
服务配置:
<system.serviceModel>
<services>
<service behaviorConfiguration="DHTestBehaviour" name="DigitallyCreated.DHTest.Business.DHTestBusinessService">
<endpoint address="" binding="netTcpBinding" contract="DigitallyCreated.DHTest.Business.IDHTestBusinessService" bindingConfiguration="DHTestNetTcpBinding" bindingNamespace="http://www.digitallycreated.net/DHTest/v1" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8090/"/>
<add baseAddress="http://localhost:8091/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DHTestBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="DHTestMembershipProvider"/>
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" findValue="CN=business.dhtestDHTest.com" />
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck" />
</clientCertificate>
</serviceCredentials>
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="DHTestRoleProvider" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="DHTestNetTcpBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
<transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
客户配置:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IDHTestBusinessService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign" />
<message clientCredentialType="UserName" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="DHTestBusinessServiceEndpointConf">
<clientCredentials>
<clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" findValue="CN=invalid"/>
<serviceCertificate>
<authentication revocationMode="NoCheck" trustedStoreLocation="LocalMachine"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="net.tcp://phoenix-iv:8090/" binding="netTcpBinding"
behaviorConfiguration="DHTestBusinessServiceEndpointConf"
bindingConfiguration="NetTcpBinding_IDHTestBusinessService"
contract="DHTest.NetTcp.Business.IDHTestBusinessService"
name="NetTcpBinding_IDHTestBusinessService">
<identity>
<dns value="business.dhtest.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
客户端用户名/密码验证码:
DHTestBusinessServiceClient client = new DHTestBusinessServiceClient();
client.ClientCredentials.UserName.UserName = "ratfink";
client.ClientCredentials.UserName.Password = "testpassword";
提前感谢您的帮助。
编辑 (2009/06/01):
我的一个朋友将我指向a blog,它回答了为什么会发生这种情况的问题。显然,当您指定 TransportWithMessageCredential 时,恰好意味着:使用消息凭据进行传输仅。这就是为什么我的证书在传输级别被忽略的原因。
但是,我不认为该问题已完成并已关闭,因为我仍然想这样做。 :) 我将研究我认为可以插入的自定义证书验证器,看看它是否有效。我会把结果回复给大家。
编辑(2009/06/08):
不,自定义证书验证器也不起作用。 WCF 根本不调用它们。
【问题讨论】:
标签: c# .net wcf security certificate