LA.NET [EN]

Jan 27

In the last post on the series we”ve seen how we can use the new ClientFormsAuthenticationMembershipProvider to authenticate a user. Today we”re going to see how we can implement the IClientFormsAuthenticationCredentialsProvider in order to create or own windows forms login form. The IClientFormsAuthenticationCredentialsProvider interface has only one method: GetCredentials. This method returns an instance of the ClientFormsAuthenticationCredentials which is responsible for keeping the login information that is going to be validated (ie, it will have to be filled with the username, password and the remember me field).

The idea here is that you should build a  class that implements the interface. This class will be responsible for getting the necessary data and packaging it into an instance of the ClientFormsAuthenticationCredentials. The recommended way of doing this is to create a new form which has the necessary windows forms” controls for getting the necessary data and implements the previous interface.

Ok, now that we know the theory, lets see how easy it is. Suppose that we”ve already created a new Form (called Login) which has two textboxes (txtUsername and txtPassword). I could also have added a remember me checkbox, but I”ve decided to always ask for the credentials during a login operation. This is what I”ve got:

public partial class Login : Form, IClientFormsAuthenticationCredentialsProvider
{
        public Login()
        {
            InitializeComponent();
        }

        private String a = “”;

        public ClientFormsAuthenticationCredentials GetCredentials()
        {
            if( this.ShowDialog() == DialogResult.OK)
            {
                return new ClientFormsAuthenticationCredentials(txtUsername.Text, txtPassword.Text, false);
            }
            return null;
        }

}

The code might be a little different from what you”d expect:

  • the form is responsible for showing itself to the user. You may be used to creating a new form and then calling ShowDialog over that instance. That would have worked here too, but you”d have to write additional code so that you could get the values from the textboxes. This approach is much more simple and involves writing less code (that makes it a clear winner, right :) ,,);
  • If the user doesn”t hit the OK, I just return null. This will automatically cancel the current login process.

By now you may be thinking on how you configure your windows forms app to use this new class. First, you need to setup the provider on the app.config file so that it knows that your app has a credentials provider. To do this, we need to setup the credentialsProvider attribute when we add the provider:

<membership defaultProvider=”ClientAuthenticationMembershipProvider”>
      <providers>
        <add name=”ClientAuthenticationMembershipProvider”
             type=”System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″
             serviceUri=”http://saturn/login/Authentication_JSON_AppService.axd”
             credentialsProvider=”login.Login, login” />
      </providers>
    </membership>

Now, to automatically get the credentials provider instantiated you only need to call the Membership.ValidateUser but this time you need to pass empty strings for both the username and password parameters:

static class Program
{
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

           if(! Membership.ValidateUser(“”, “”) )
            {
                return;
            }
            Application.Run(new Form1());
        }
}

If you run the previous code (I”m assuming that you”ve already set up the server side as explained before), you”ll automatically get the login dialog when the ValidateUser method is called. As a bonus, you”ll see that you”ll have 3 chances for getting the introducing the correct credentials. If you miss those three attempts and have similar code to the one I”ve show above, the application will be automatically terminated (it won”t run the main form).

What could have been a cool feature ended up being a “wanna be” cool feature. Unfortunately, you cannot setup the number of retries. It”s simply hard coded to three, as you can see by looking at the ValidateUserCore method with .NET Reflector. Now, I can tell you that I”ve tried understanding this, but I simply didn”t found any good explanation for this behavior. After all, how hard would it be to get the number of retries from an attribute that would be setup on the app.config file???

Anyway, there are still one or two things to talk about these providers, but I”ll leave them for a future post.

3 comments so far

  1. Steve Allen
    6:20 am - 6-12-2008

    The default membership provider in aspnet uses the “ApplicationName” combined with username/password to authenticate. How does one set he ApplicationName (i.e.; aspnet_Applications table in the database) using client services?

  2. Luis Abreu
    8:19 am - 6-12-2008

    You don”t. You do it at the web.config file of your site that is hosting the provider…

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>