title: WCF wsDualHttpBinding and UserNamePasswordValidator
body: <p>I'd like to use UserNamePasswordValidator with wsDualHttpBinding but here is my problem:</p>
  
  <p>If I use: </p>
  
  <p><code>&lt;security mode="Message" &gt;
              &lt;message clientCredentialType="UserName"  /&gt;
            &lt;/security&gt;</code></p>
  
  <p>I get this exception:</p>
  
  <p>Identity check failed for outgoing message. The expected DNS identity of the remote endpoint was 'localhost' but the remote endpoint provided DNS claim 'Theater'. If this is a legitimate remote endpoint, you can fix the problem by explicitly specifying DNS identity 'Theater' as the Identity property of EndpointAddress when creating channel proxy.</p>
  
  <p>If I change the DNS to Theater then it times out. If i don't use the security mode the UserNamePasswordValidator doesn't get called. I read that if I would use wsHttpBinding I could set the security to TransportWithMessageCredential and that would work but I need the dual.
  Here is the config:</p>
  
  <pre><code>     &lt;system.serviceModel&gt;
       &lt;bindings&gt;
        &lt;wsDualHttpBinding&gt;
          &lt;binding maxReceivedMessageSize="268435456" maxBufferPoolSize="268435456"&gt;
            &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="268435456" maxBytesPerRead="4096" maxNameTableCharCount="2147483647" /&gt;
                &lt;security mode="Message" &gt;
              &lt;message clientCredentialType="UserName"  /&gt;
            &lt;/security&gt; 
          &lt;/binding&gt;
        &lt;/wsDualHttpBinding&gt;
      &lt;/bindings&gt;
            &lt;services&gt;
        &lt;service name="WcfService1.Service1" behaviorConfiguration="ServiceBehavior"&gt;      
          &lt;endpoint address="" binding="wsDualHttpBinding" contract="WcfService1.IService1"&gt;
            &lt;identity&gt;
              &lt;dns value="localhost" /&gt;
            &lt;/identity&gt;
          &lt;/endpoint&gt;
          &lt;endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /&gt;
        &lt;/service&gt;
      &lt;/services&gt;   
      &lt;behaviors&gt;
        &lt;serviceBehaviors&gt;
          &lt;behavior name="ServiceBehavior"&gt;
            &lt;!-- To avoid disclosing metadata information, set the values below to false before deployment --&gt;
            &lt;serviceMetadata httpGetEnabled="true"/&gt;
            &lt;serviceCredentials&gt;
              &lt;userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfService1.OperatorValidator, WcfService1"/&gt;
              &lt;serviceCertificate findValue="Theater" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/&gt;
            &lt;/serviceCredentials&gt;   
          &lt;/behavior&gt;
        &lt;/serviceBehaviors&gt;
      &lt;/behaviors&gt;
      &lt;protocolMapping&gt;
        &lt;add binding="basicHttpsBinding" scheme="https" /&gt;
      &lt;/protocolMapping&gt;
      &lt;serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /&gt;
    &lt;/system.serviceModel&gt;
    &lt;system.webServer&gt;
      &lt;modules runAllManagedModulesForAllRequests="true" /&gt;
      &lt;!--
          To browse web app root directory during debugging, set the value below to true.
          Set to false before deployment to avoid disclosing web app folder information.
        --&gt;
      &lt;directoryBrowse enabled="true" /&gt;
    &lt;/system.webServer&gt;
  </code></pre>
  
  <p>Validator: </p>
  
  <pre><code>namespace WcfService1
  {
      public class OperatorValidator : UserNamePasswordValidator
      {
  
          public override void Validate(String userName, String password)
          {
              if (String.IsNullOrEmpty(userName) || String.IsNullOrEmpty(password))
                  throw new SecurityTokenException("Username and password cannot be empty.");
  
              try
              {
                  using (Theater4Entities entities = new Theater4Entities())
                  {
  
                      Byte[] passwordBytes;
  
                      using (SHA1CryptoServiceProvider provider = new SHA1CryptoServiceProvider())
  
                      {
                          passwordBytes = provider.ComputeHash(Encoding.UTF8.GetBytes(password)); 
                      }
  
                      Operator currentOperator = entities.Operator.FirstOrDefault(op =&gt; op.UserName == userName);
  
  
                      if (currentOperator == null || !passwordBytes.SequenceEqual(currentOperator.UserPassword))
  
                          throw new SecurityTokenException("Username or password does not match.");
  
  
                  }
              }
              catch (SecurityTokenException)
              {
                  throw;
              }
              catch
              {
                  throw new SecurityTokenException("Unexpected error occured.");
              }
          }
      }
  }
  </code></pre>
  
  <p>And here is where I catch the exception:</p>
  
  <pre><code>public WAF1ClientViewModel()
  {
      _callbackService = new RentalServiceCallback();
      InstanceContext context = new InstanceContext(_callbackService);
      _client = new Service1Client(context);
   }
  .
  .
  .
    private void LoginExecuted(PasswordBox passwordBox)
      {
          try
          {
              _client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
  
              _client.ClientCredentials.UserName.UserName = UserName;
              _client.ClientCredentials.UserName.Password = passwordBox.Password;
  
              _client.Login(UserName);
              _isLoggedIn = true;
              OnLoginSuccess(); 
          }
          catch
          {
              OnLoginFailed();
          }
      }
  </code></pre>
  
  <p>I would be open to any alternative method. </p>