UserNamePasswordValidator和证书

时间:2011-04-05 16:56:53

标签: .net binding tcp validation

我有一个使用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,在这两种情况下,该服务都需要启动证书。

我错过了什么吗?自定义用户名和密码验证程序是否始终需要证书?

1 个答案:

答案 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或您正在使用的任何内容。