Custom Authentication in WCF

Author: Ryan Olshan

WCF provides for custom username- and password-based authentication using UserNamePasswordValidator.  The below code demonstrates implementing this.

Let's presume your service looks as follows:

namespace MyService
{
   public class Service : IService
   {
      //...
   }
}

Step 1 - Create a class that inherits UserNamePasswordValidator and override the Validate method.

using System.IdentityModel.Selectors;
using System.ServiceModel;

namespace MyService
{
   public class AuthenticationValidator : UserNamePasswordValidator
   {
      public override void Validate(string userName, string password)
      {
         bool validate = SomeCode.Validate(userName, password);
         if (!validate)
         {
            throw new FaultException("Unable to authenticate");

         }
      }
   }
}

Step 2 -  Go to Internet Information Services (IIS) Manager > Server Certificates and click Self-Signed Certificate on the right.  Follow the wizard and make note of the domain name generated for the certificate.  This value will be used for findValue in Web.config in Step 3.

Step 3 - Update your Web.config file to look similar to the following:

<?xml version="1.0"?>
<configuration>
   <system.serviceModel>
      <services>
         <service name="MyService.Service" behaviorConfiguration="MyServiceBehaviorConfig">
            <endpoint address="/Service" binding="wsHttpBinding" contract="MyService.IService" bindingConfiguration="MyServiceBindingConfig"/>
         </service>
      </services>
      <bindings>
         <wsHttpBinding>
            <binding name="MyServiceBindingConfig">
               <security mode="Message">
                  <message clientCredentialType="UserName"/>
               </security>
            </binding>
         </wsHttpBinding>
      </bindings>
      <behaviors>
         <serviceBehaviors>
            <behavior name="MyServiceBehaviorConfig">
               <serviceCredentials>
                  <serviceCertificate findValue="mydomain.com" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
                  <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyService.AuthenticationValidator, MyService"/>
               </serviceCredentials>
            </behavior>
         </serviceBehaviors>
      </behaviors>
   </system.serviceModel>
</configuration>

Step 4 - Assuming you referenced the service as MyService when you added it as a service reference, you can access the WCF service as follows:

MyService.MyServiceClient client = new MyService.MyServiceClient();
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
// WCF method calls here
client.Close();

Authentication using the custom validator created in Step 1 will now be used by WCF.

© 2016 RK Consulting. All rights reserved.