Carl
Carl

Reputation: 406

WCF Custom Authentication Provider

I am trying (desperately) to get a customer authentication provider working for my WCF service. So far I have the following code;

web.config

      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom"  customUserNamePasswordValidatorType="MyNamespace.CustomUserNameValidator, MyNamespace" />
      </serviceCredentials>

     <wsHttpBinding>
    <binding name="wsHttpBindingConfig" >
      <security mode="Message">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </wsHttpBinding>

      <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>

Custom authenticator class;

public class CustomUserNameValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        // have security details been provided?
        if (null == userName || null == password)
        {
            throw new ArgumentNullException();
        }

        // authenticate user
        if (!(userName == "test" && password == "test"))
        {
            // This throws an informative fault to the client.
            throw new FaultException("SecurityFailed");
        }
    }
}

Everything compiles ok, but when I use the WCF test client from visual studio to call a method called Ping (below), the custom authenticator never gets used. The Ping method just executes and any breakpoint I have in my CustomUserNameValidator class.

Why would this be? All help appreciated.

Upvotes: 0

Views: 2075

Answers (3)

Matt Klepeis
Matt Klepeis

Reputation: 1722

I've taken all of the information that you've provided and created a template web.config. I would envision it looking something like this.

<system.serviceModel>
   <services>
     <service name="<YourNameSpace>.<ServiceName>" <behaviorConfiguration="<YourNameSpace>.<BehaviorName>">
      <endpoint
        address=""
        binding="wsHttpBinding"
        bindingConfiguration="wsHttpBindingConfig"
        contract="<YourNameSpace>.<ServiceInterface>"
      />
         <!--Notice the binding is mexHttpsBinding, default is http-->
      <endpoint 
        address="mex" 
        binding="mexHttpsBinding" 
        contract="IMetadataExchange" 
      />
     </service>
   </services>
<behaviors>
   <serviceBehaviors>
       <behavior name="<YourNameSpace>.<BehaviorName>">
          <!--Notice the httpsGetEnabled, default is http-->
      <serviceMetadata httpsGetEnabled="true"/>
           <serviceDebug includeExceptionDetailInFaults="false"/>
           <serviceCredentials>
              <userNameAuthentication
                 userNamePasswordValidationMode="Custom"                 
                 customUserNamePasswordValidatorType="<YourNameSpace>.CustomUserNameValidator, <YourNameSpace>"
              />
           </serviceCredentials>
       </behavior>
   </serviceBehaviors>
</behaviors>
<bindings>
  <wsHttpBinding>
    <binding name="wsHttpBindingConfig">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  <wsHttpBinding>
</bindings>

Upvotes: 0

Samuel Jack
Samuel Jack

Reputation: 33260

In the line where you have

customUserNamePasswordValidatorType="MyNamespace.CustomUserNameValidator, MyNamespace"

the second part of the type (you currently have "MyNamespace") should be the name of the assembly containing the type, without any file extension.

See this question for more help.

Upvotes: 1

Matt Klepeis
Matt Klepeis

Reputation: 1722

A few suggestions.

  1. The WCFTestClient is not the best application. You would be better off using a tool like SOAPUI (downloadable at www.soapUI.org). The WCFTestClient does not import all configuration settings and is not the best method for testing.
  2. When I use CustomAuthentication I set my binding up like this:

    <wsHttpBinding>  
        <binding name="wsHttpBindingConfig" >  
           <security mode="TransportWithMessageCredentials">  
             <message clientCredentialType="UserName" />  
           </security>  
        </binding>  
    </wsHttpBinding> 
    

I assume you will like some form of security down the line. Testing with a self signed SSL cert on your machine pretty easy. There is more information about how to do this here.

Upvotes: 0

Related Questions