WCF custom username and password validation is not

2019-08-05 09:49发布

问题:

I have a WCF service hosted on IIS 7.5 with the settings of basicHttpBinding binding and TransportWithMessageCredential security. I would like to send a FaultException to the client in case of failed authentication but unfortunately the Validate method of custom validator class is not executed. I have read here, that custom validator works only for self-hosting scenario: Is it true, or I made a mistake somewhere?

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

        if (!(userName == MobilApp.Helper.SiteGlobal.UserName && password == MobilApp.Helper.SiteGlobal.Password))
        {
            throw new FaultException("Unknown Username or Incorrect Password");
        }

    }
}

web.config:

<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="True" />
<bindings>
  <basicHttpBinding>
    <binding name="ServiceBinding" useDefaultWebProxy="false">          
      <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Certificate" />
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="Service.TestService" behaviorConfiguration="CustomValidator">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="ServiceBinding"
      bindingNamespace="https://service/TestService/"
      contract="Service.ITestService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="https://service/TestService/" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="CustomValidator">
      <useRequestHeadersForMetadataAddress/>
      <serviceMetadata httpGetEnabled="false" httpsGetEnabled="True" httpsGetUrl="wsdl" />
      <serviceDebug includeExceptionDetailInFaults="false" httpHelpPageEnabled="false" httpsHelpPageEnabled="true" />
      <serviceCredentials>
        <clientCertificate>
          <authentication
            certificateValidationMode="ChainTrust"
            revocationMode="NoCheck" />
        </clientCertificate>
        <serviceCertificate
          findValue="test.com"
          x509FindType="FindBySubjectName"
          storeLocation="LocalMachine"
          storeName="My" />
        <userNameAuthentication
          userNamePasswordValidationMode="Custom"
          customUserNamePasswordValidatorType="ServiceUserNamePasswordValidator, Service" />
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

Thank you.