我有一个使用net tcp绑定和自定义UserNamePasswordValidator的Web服务。用户名和密码由客户端在Credentials.UserName.UserName和Credentials.UserName.Password中发送。我的服务主机设置如下:
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = myCustomValidator;
host.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;
如果使用绑定的SecurityMode = TransportWithMessageCredential和ClientCredentialType = MessageCredentialType.UserName但需要证书,则它可以正常工作。
我想让它在没有证书的情况下工作。如果我将绑定的SecurityMode更改为None,则服务已启动,但我的UserNamePasswordValidator类从未被调用过。
我尝试了SecurityMode = Message和SecurityMode.Transport,在这两种情况下,该服务都需要启动证书。
我错过了什么吗?自定义用户名和密码验证程序是否始终需要证书?
答案 0 :(得分:2)
不幸的是,WCF不允许您以纯文本形式通过网络发送用户名/密码。你仍然可以做到,但它要求你创建一个自定义绑定,就像这个人here。这意味着您必须使用证书进行加密。注意,这与证书身份验证不同,所以不要在这方面感到困惑。所有这一切意味着您必须安装公开公钥的证书。所以你的服务器配置看起来像这样:
<bindings>
<wsHttpBinding>
<binding name="CustomAuthentication">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
...
<serviceBehaviors>
<behavior name="CustomPasswordAuthentication">
<serviceMetadata httpGetEnabled="true" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="MyCertificateName" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="Root" />
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyCompany.WebServices.CustomUsernamePasswordValidator, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
客户端:
client.ClientCredentials.UserName.UserName = "hello";
client.ClientCredentials.UserName.Password = "hello";
client.ClientCredentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
client.Open();
希望这会有所帮助。编辑:只需将wsHttpBinding更改为TCP或您正在使用的任何内容。