WIF: WIF Adding Values to WCF security (Security Mode: Message, Client Credential Type: User Name / Password)

How can WIF help in simplifying WCF security ?

Traditionally we have UserNamePasswordValidator class to do the job from WCF layer (https://msdn.microsoft.com/en-us/library/aa702565.aspx).

 

But not good for developer, they would like to implement the business logic inside methods and will never like to take headache for implementing security.

 

WIF to rescue

Using WIF we can take out the security aspect completely out of WCF and implement at level of STS.

This will help developers in concentrating on core BL development rather than on security implementation.

 

Steps to validate the User name pass word via WIF provided STS service.

  1. Create a blank WCF project, add the operation with relevant business logic.
  2. We don’t have to add any security layer on this service, that will be implemented at STS layer.
  3. Once the development is done, it is just matter of few click with few line of code to add the security layer. WIF makes it simple and isolated process from main business logic project.
  4. Right click the project and say Add STS Reference.
  • Specify the WCF service / Application URI

           

  • Select – Create a new STS project

            

  • Almost done – Click Finish

             

 

 

Now we have brand new STS project added to our main solution

 

1.  Checking configuration file for STS 

      <ws2007HttpBinding>

        <binding name="ws2007HttpBindingConfiguration">

          <security mode="Message">

            <message establishSecurityContext="false" />

          </security>

        </binding>

      </ws2007HttpBinding>

 2.  We need the client to send user name password, right !

  1. So, let us modify this (By default, the client credential type is windows).
  2. Setting client credential type as User Name.

      <ws2007HttpBinding>

        <binding name="ws2007HttpBindingConfiguration">

          <security mode="Message">

            <message establishSecurityContext="false" clientCredentialType="UserName"/>

          </security>

        </binding>

      </ws2007HttpBinding> 

 

3. Also add the service certificate inside service behavior.

         <serviceCredentials>

            <serviceCertificate findValue="saurabh.xyz.microsoft.com" storeLocation="LocalMachine" storeName="My" x509FindType="FindByIssuerName"/>

         </serviceCredentials>

 

4. Now, the flow will be like this.

5. Now the STS is configured to ask for a User Name token, next step is to validate the same.
     We can use the WIF provided “UserNameSecurityTokenHandler“ to validate the incoming token.

  • Add a new class implementing the same.

         public class CustomUserNameSecurityTokenHandler : UserNameSecurityTokenHandler  Override the canValidateToken and ValidateToken methods

 

 public override bool CanValidateToken

        {

            get { return true; }

        }

 

 public override ClaimsIdentityCollection ValidateToken(SecurityToken token)

        {

            UserNameSecurityToken usernameToken = token as UserNameSecurityToken;

            if (usernameToken == null)

            {

               
throw new ArgumentException("usernameToken", "The security token is not a valid username security token.");

            }

             string username = usernameToken.UserName;

            string password = usernameToken.Password;

             if (("myUser"== username && "myPass" ==password))

            {

               IClaimsIdentity identity = new ClaimsIdentity();

                identity.Claims.Add(new Claim(WSIdentityConstants.ClaimTypes.Name,username));

               return new ClaimsIdentityCollection(new IClaimsIdentity[] { identity });

            }

             throw new InvalidOperationException("The username/password is incorrect");

        }

  

6. Once we are done with this, let us refer the same from the configuration file.

Add below tag inside configuration tag

  <microsoft.identityModel>

    <service>

      <securityTokenHandlers>

        <remove type="Microsoft.IdentityModel.Tokens.WindowsUserNameSecurityTokenHandler,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

        <add type="CustomUserNameSecurityTokenHandler,
App_Code"/>

      </securityTokenHandlers>

    </service>

  </microsoft.identityModel>

 

7. Now if we try to re-build it will give an error.

 

8. Please add below code to correct this.

  <configSections>

    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />

  </configSections>

 

 9. That’s it. We have successfully added the security layer using WIF inside the WCF service.

  1. Security is no more a head ache for WCF developer, it is outsourced to WIF in a very easy way.
  2. Rebuid the STS project and right clie

 

10 . Next step is to create the client project and add service reference to WCF service.

 

11. Add following code to main method

         static void Main(string[] args)

        {

          ServiceReference1.Service1Client proxy = new ServiceReference1.Service1Client();

           proxy.ClientCredentials.UserName.UserName = "myUser";

           proxy.ClientCredentials.UserName.Password = "myPass";

            Console.WriteLine(proxy.GetData(123));

        }

 

 12. We can validate the validation by adding break point inside the “CustomUserNameSecurityTokenHandler.cs” class.

 

 

Hope this helps !