0

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.

sada
  • 584
  • 2
  • 8
  • 25
  • UserNamePasswordValidator **does not** require self-hosting. I use it in IIS –  Aug 15 '14 at 12:35
  • Does your service operation gets called and what response do you get? – t3z Aug 15 '14 at 15:16
  • The test console client in VS 2010 stops in client proxy class with error message: 'The username is not provided. Specify username in ClientCredentials.' and in the console window:'The communication object, System.ServiceModel.Channels.Servi ceChannel, cannot be used for communication because it is in the Faulted state. Server stack trace: at System.ServiceModel.Channels.CommunicationObject.ThrowIfDisposedOrNotOpen( )...', but I would catch a clean FaultException with message 'Unknown Username or Incorrect Password'. :( – sada Aug 15 '14 at 15:51
  • Actually the 'Validate' method is invoked when the username and password are not empty but the validation gives back FaultException in vain, because the client catches just CommunicationException not FaultException. When either username or password or both of them are empty the Validation code is not invoked. Why would be it the way I want? – sada Aug 15 '14 at 18:24

0 Answers0