2011-04-05 105 views
2

我有一个使用net tcp绑定和自定义UserNamePasswordValidator的web服务。用户名和密码由客户端在Credentials.UserName.UserName和Credentials.UserName.Password中发送。我的服务主机被设置如下:UserNamePasswordValidator和证书

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,并且在这两种情况下,服务都需要一个证书才能启动。

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

回答

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或任何您使用的。