18 March, 2011

How to: WCF and custom Authentication (username/password)

This post details how you can customize the way users of your WCF-services are authenticated. But, before engaging in this procedure, let’s first establish some terminology/concepts:
Authentication: to establish the identity of an individual/entity.
Authorization: to determine whether an authenticated (identified) individual is allowed access to a system. You Authorize access to a system.
This post is about Authentication (identity establishment)
Authentication is a subject that is pretty hard to deal with yourself. A number of proven and established mechanisms already are in place solving this functionality out-of-the-box in WCF. Due to the very nature of an identity token (it carries the “identity” of an individual), it is shielded with proper usage of cryptography. Therefore – it is very hard to do much in this area yourself. It a completely different story when it comes to Authorization (another post).
Where does Authentication fit into the overall picture? As evident from the figure – the Authentication is the first action taken when an incoming request is received. It makes actually a lot of sense, as it is not possible to perform Authorization before you have established the identity (Authentication) of the incoming user/system.
image
In native WCF - the following security token types (credential types) are supported:
    • Username Token (points by default to an ASP.NET database)
    • X.509 Certificate Token (digital certificates)
    • Kerberos Token (Windows Active Directory)
    • SAML Token (generic Security Assertion Markup Language; also signed with certificate)
As seen, a number of implementations are already in place. So - when would you have a need for this proposed customization? The only one I can think of is, if you are not using e.g. the standard ASP.NET Membership database, but you have rolled your own user storage. In such scenario, it might make sense to use this customization. And the customization in play here would most often be: username/password authentication.
 How do you establish your own Username/Password Authentication?
The entire solution is seen here. It is a Client console, Server Console and a shared library with Contracts (ICalculatorService). Sharing a contract between the two makes sense when you have control of both Client and Server as is the case in this example.
image
The various parts are seen below.
Shared ContractThe shared contract is simply a type safe way of having both Client/Server knowing the types and methods used.
[ServiceContract]
public interface ICalculatorService{
    [OperationContract]
    int Add(int a, int b);

    [OperationContract]
    int Subtract(int a, int b);
}



ServerThe server side is the place where the “meat” is. But, as WCF is constructed in a very clever “stack-like” manner, security is deliberately kept out of the business logic (of the Calculator in this case!). Therefore, you do not see anything security related in the below service implementation. The security is kicking in long time before in the stack before the call ultimately reaches the below business-logic (see the illustration above).
public class CalculatorService : ICalculatorService {
    public int Add(int a, int b)
    {
        return a + b;
    }

    public int Subtract(int a, int b)
    {
        return a - b;
    }
}

The security (and in this case Authentication-part) is created as a custom override of UserNamePasswordValidator. If the incoming credentials do not match user=”Ole” and password=”Pwd”, an AuthenticationException is thrown. These values are of-course to be looked up in your own user storage (a database or…?) Should the credentials however match an identity in your store, no exceptions are thrown.
/// <summary>
/// Custom impl. of u/p validation./// </summary>class UsernameAuthentication : UserNamePasswordValidator {
    /// <summary>
    /// When overridden in a derived class, validates the specified username and password.
    /// </summary>
    /// <param name="userName">The username to validate.</param><param name="password">The password to validate.</param>
    public override void Validate(string userName, string password)
    {
        //TODOs: Lookup match in user storage (DB?).
        var ok = (userName == "Ole") && (password == "Pwd"); 
        if(ok == false)
            throw new AuthenticationException("u/p does not match");
    }
}

Important: Now – you might ask yourself - where is the identity matching the provided credentials actually being set? After all, this is what we are after here; to convert a set of credentials => an identity? As long as we are inheriting from the UserNamePasswordValidator, this is taken care of for us behind the scenes. The UserNamePasswordValidator will create a NameClaim in the authentication chain taking the username as “name”. The NameClaim (= username) is considered an Identity in this scenario.

Server Configuration
To make your service use this custom validation stuff, you need to tweak some settings in <app>.config for the service. Especially, the <usernameAuthentication> settting needs to have a validationMode = “Custom”.
<configuration>
  <system.serviceModel>
    
    <services>
      <service name="Server.CalculatorService" behaviorConfiguration="customCred">
        <endpoint address="net.tcp://localhost:9090/CalcSvc"
                  binding="netTcpBinding"
                  bindingConfiguration="secUP"
                  contract="SharedContracts.ICalculatorService"/>
      </service>
    </services>
    
    <bindings>
      <netTcpBinding>
        <binding name="secUP">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    
    <behaviors>
      <serviceBehaviors>
        <behavior name="customCred">
          <serviceCredentials>
            <!--Service identity + encryption certificate-->
            <serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" 
                                storeLocation="LocalMachine" storeName="My" />
            
            <userNameAuthentication userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="Server.Auth.UsernameAuthentication, Server" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

As seen, a (reasonable) simple configuration is required.



ClientThe clients needs to provide some credentials to the service (we just set this up!).
static void Main(string[] args)
{
    Console.WriteLine("Client - starting...");
    Console.WriteLine("Press key to start...");

    Console.Read();

    var fac = new ChannelFactory<ICalculatorService>("tcpEP");
    //set credentials
    fac.Credentials.UserName.UserName = "Ole"; 
    fac.Credentials.UserName.Password = "Pwd";

    var prox = fac.CreateChannel();
    using (prox as IDisposable)
    {
        var res = prox.Add(1, 2);
        Console.WriteLine("Result: {0}", res);
    }

    Console.Read();
}

That’s about what it takes to create a custom username/password validation against your own data store. Happy coding, guys!

Update: Download project here
http://www.clauskonrad.net/download.ashx?id=15


Technorati Tags: ,

29 comments:

Anonymous said...

Not great. Want a generic design without hard coding

Anonymous said...

Can you provide downloadable solution project?

Claus Konrad said...

There is no hardcoding here?
If you are refering to the user/pwd, then it's just for the sake of demonstration purpose.

Claus Konrad said...

Updated with downloadable project.

Anonymous said...

Maybe want to take it out of source control so the project loads for others.

Baz L said...

Questions:

1. Does the client need to supply this information for *every* request?
2. Is there some way to authenticate once, get some sort of token and use this for subsequent calls?

Claus Konrad said...

1: The credentials are attributed to the proxy you create in the client runtime (using the factory). Every time you ask a factory to create a proxy - you need to set these values to gain a valid proxy. Otherwise communication etablishment will fail.

2: As long as you use the same proxy instance - you can call as many times as you want. No need for re-authenticate; the WCF-plumbing takes care of this.

Display name said...

I want to download your source code for study, But cannot.

Thichca2 said...

Can I provide custom authenticate in addition to standard Windows Authentication.
I have a service that I want to ensure that only my client library can access this service but no one else.
application can use my client library to access the service by providing Windows user account but internally my library also is authenticated with the service.
Thanks

Claus Konrad said...

Have a look at this:

http://blog.clauskonrad.net/2010/04/wcf-restrict-which-clients-can-call.html

for IT the said...

Authentication identity establishment WCF Traininguseful article

Dot Net Training in Chennai |

afiah b said...

Thank you for allowing me to read it, welcome to the next in a recent article. And thanks for sharing the nice article, keep posting or updating news article.
Java training in Chennai

Java training in Bangalore

sasitamil said...


This is quite educational arrange. It has famous breeding about what I rarity to vouch. Colossal proverb.
This trumpet is a famous tone to nab to troths. Congratulations on a career well achieved. This arrange is synchronous s informative impolites festivity to pity. I appreciated what you ok extremely here 


Selenium training in bangalore
Selenium training in Chennai
Selenium training in Bangalore
Selenium training in Pune
Selenium Online training

Maria said...

All good. I am a newcomer, so I jerked until the money was withdrawn. I waited 2 days on Yandex. Thanks to the admins and support service for listening to my whining on the forum and in the chat. Play people! Do not be greedy. All the rules with this casino perfect the casino I often spend my time here

Deepali M said...

After read this blog i feel very satisfied to learn some thing. Wonderful content to read because it is very easy to read. Great work.



Full Stack Developer Training Online | Full Stack web Developer Training | Full Stack Developer Certification | Full Stack Developer Course | Full Stack Developer Training


amsa leka said...

Thanks for your great and helpful presentation I like your good service. I always appreciate your post. That is very interesting I love reading and I am always searching for informative information like this.Also Checkout: blockchain technology training chennai | blockchain training institute in chennai | cryptocurrency training in chennai | blockchain training center in chennai

Soumitasai said...

Outstanding blog thanks for sharing such wonderful blog with us ,after long time came across such knowlegeble blog. keep sharing such informative blog with us.

Check out : big data training in velachery
big data hadoop training cost in chennai
big data training in chennai omr
big data training in chennai velachery

IT Tutorials said...

Really useful information. Thank you so much for sharing.It will help everyone.Keep Post. RPA training in chennai | RPA training in Chennai with placement | UiPath training in Chennai | UiPath certification in Chennai with cost

Diya shree said...

Good job and thanks for sharing such a good blog You’re doing a great job. Keep it up !!

PMP Certification Fees | Best PMP Training in Chennai |
pmp certification cost in chennai | PMP Certification Training Institutes in Velachery |
pmp certification courses and books | PMP Certification requirements |
PMP Training Centers in Chennai | PMP Certification Requirements | PMP Interview Questions and Answers

Anonymous said...

Nice article to read, in fact, I am interested to learn the carving art, and your blog inspires me more and more. Thank you for sharing such a wonderful blog.
cruise ship training and placement in chennai
best visual communication insitute in chennai
Carving classes in Chennai
hotel management institute in chennai
hotel management course in chennai
hotel management College in chennai
Fashion Design Course in Chennai

Amirtha Gowri said...

Thanks for sharing such a Wonderful blog. This is such exact information I am been searching for. Keep post

Check Out:
react js tutorial
it courses in chennai
react js classes near me

Amirtha Gowri said...

It’s interesting content and Great work. Definitely, it will be helpful for others. I would like to follow your blog. Keep post

Check out:
Selenium training courses in chennai
Selenium training center in chennai
Selenium training in chennai quora
Selenium course fees in chennai

Amit said...

Amazing blog. I like t know more about such technical stuff. Thanks for sharing
Fashion Designing course in Dehradun
Drawing & Painting Course in Dehradun
Fine Arts Course in Dehrdun
Animation & Multimedia Course in Dehradun
Journalism & Mass Communication Course in Dehradun
Commerce & Management Courses in Dehradun

IT Tutorials said...




Get the most advanced AWS Course by Professional expert. Just attend a FREE Demo session.
For further details call us @ 9884412301 | 9600112302
AWS training in chennai | AWS training in velachery

Chris Hemsworth said...

The article is so informative. This is more helpful for our
Learn best software testing online certification course class in chennai with placement
Best selenium testing online course training in chennai
Best online software testing training course institute in chennai with placement
Thanks for sharing.

divi said...

thanks for your information really good and very nice web design company in velachery

kishore said...

I read your great post and I really enjoyed this. The content was very easy to understand for readers.
Unix Training in Chennai
Unix Course in Chennai
Pega Training in Chennai
JMeter Training in Chennai
Corporate Training in Chennai
Tableau Training in Chennai
Job Openings in Chennai
Placement Training in Chennai
Oracle Training in Chennai
Unix Training in Adyar
Unix Training in Anna Nagar

sasi said...

I really enjoyed this article. I need more information to learn so kindly update it.
Salesforce Training in Chennai
salesforce training in bangalore
Salesforce Course in Chennai
best salesforce training in bangalore
salesforce institute in bangalore
salesforce developer training in chennai
web designing course in madurai
php training in coimbatore

subhashini said...

Such a great blog.Thanks for sharing.........
Tally Course in Chennai
Tally Classes in Chennai
Tally training coimbatore
Tally course in madurai
Tally Training Institute in Chennai
Tally coaching centre in coimbatore
Tally Training in madurai
Software Testing Training in Chennai

iPhone/XCode - not all cases are equal!

This bit me! Having made some changes to an iPhone application (Obj-C); everything worked fine in the simulator. But, when deploying the s...