自定义UserNamePasswordValidator未调用

时间:2016-05-25 10:39:59

标签: wcf basic-authentication

我正在尝试使用BasicHttpBinding和使用用户名/密码进行身份验证来设置WCF Web服务。我做了自定义身份验证类。但是,它永远不会被调用(通过调试验证)。这是我的web.config:

  <system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Compareware_WebApp.webservices.AuthenticationValidator, Compareware_WebApp" />
      </serviceCredentials>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding">
      <security mode="TransportCredentialOnly">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="Compareware_WebApp.webservices.Accounts">
    <endpoint address="/webservices/Accounts.svc" binding="basicHttpBinding"
      bindingConfiguration="BasicHttpBinding" name="BasicEndpoint"
      contract="Compareware_WebApp.webservices.IAccounts" />
  </service>
</services>
<client />

这是我的身份验证类:

namespace Compareware_WebApp.webservices

{

public class AuthenticationValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if (null == userName || null == password)
        {
            throw new ArgumentNullException();
        }

        if (!Membership.ValidateUser(userName, password))
        {
            // This throws an informative fault to the client.
            throw new FaultException("Unknown Username or Incorrect Password");
        }
    }
}

}

我做错了什么?

2 个答案:

答案 0 :(得分:4)

我也遇到了这个问题,我得到了解决方案。如果您想调用Validate的{​​{1}}方法,那么您必须使用UserNamePasswordValidator安全性。

注意:您必须在IIS服务器上托管WCF服务,并且必须为您的网站启用SSL,否则它将无效。如果我们使用TransportWithMessageCredential而不是我们的网站启用SSL。

WCF服务器Web.config文件

TransportWithMessageCredential

服务身份验证类

<?xml version="1.0"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttp">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="TransportWithMessageCredential.Service1" behaviorConfiguration="wsHttpBehavior">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttp" contract="TransportWithMessageCredential.IService1">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8080/WCFDemo"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TransportWithMessageCredential.ServiceAuthanticator, TransportWithMessageCredential"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <compilation debug="true"/>
  </system.web>
</configuration>

WCF客户端app.config文件

 public class ServiceAuthanticator : UserNamePasswordValidator
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        public override void Validate(string userName, string password)
        {
            if (String.IsNullOrEmpty(userName) || String.IsNullOrEmpty(password))
            {
                throw new FaultException("Please, Provide the username and password!!!");
            }

            if (userName != "abc" || password != "abc")
            {
                throw new FaultException("Sorry, Invalid username or password!!!");
            }
        }
    }

调用WCF服务的客户端程序

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService1">
                    <security mode="TransportWithMessageCredential">
                        <transport clientCredentialType="None" />
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://kalpesh-pc/WCFAuth/Service1.svc" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="WSHttpBinding_IService1">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

快乐编码......

:)

答案 1 :(得分:0)

据我了解,

传输需要HTTPS加密凭据,如果没有SSL,则会引发异常。 TransportCredentialOnly将以纯文本形式发送凭据,并且未加密,建议仅用于测试。 因此,您的凭据是通过传输发送的。因此必须调整<Transport>标签,而不是<Message>

以下对我有用:

<security mode="TransportCredentialOnly">
    <transport clientCredentialType="Basic"/>
</security>