Feb 07

Application services IV: authenticating the user in an offline scenario

Posted in ASP.NET C#      Comments Off on Application services IV: authenticating the user in an offline scenario

In my previous posts I”ve been talking about the basic features introduced by the new Applications Services which were added during the latest release of the .NET platform. Today we”ll see how easy it is to configure our windows form app so that it is able to authenticate a user in an offline scenario.

As you might expect, you”ll only be able to validate a user (on an offline scenario) if that user has already been validated previously in an online scenario. So, the 1st thing you need to do is to change your app.config file so that the hash of the password is stored in the machine. To achieve this, you need to set the savePasswordLocally attribute of the provider entry:

<add name=”ClientAuthenticationMembershipProvider”
             type=”System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35″
             credentialsProvider=”login.Login, login” />

Even though this step is required in order to save a local copy of the hash of the password, it is not enough for making the platform authenticate the credentials against the local saved copy of a previously successful authentication. The offline authentication scheme will only be used when the ConnectivityStatus.IsOffline is set to true. So, you need to change your startup code to something like this for authenticating a user in an offline scenario:

ConnectivityStatus.IsOffline = true;
if(! Membership.ValidateUser(“”, “”) )
Application.Run(new Form1());

By now you must be wondering where the platform is saving the hash of the password. If you don”t do anything,the hash will be saved in a file named User_username.clientdata in a folder named after your windows app (placed inside the user”s app data folder). Just replace username with the username of the user that is trying to log on and you should find the file by performing a search on your disk. If you open that file,you should find something like this on it:

<?xml version=”1.0″ encoding=”utf-8″?>

As you can see, there”s a lot more info besides the password hash+salt used for authenticating the user in an offline scenario. For instance, roles can also be cached…

Currently, you can also save the user info in an SQL Compact database. To do that, you”ll need to specify a SQL Compact connection string or you can simply use the special connection string “Data Source=|SQL/CE|”. Here”s what you need in order to achieve this:

<add name=”ClientAuthenticationMembershipProvider”
connectionStringName=”Data Source=|SQL/CE|”
            type=”System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35″
            credentialsProvider=”login.Login, login”

Do notice that this will only work in x86 builds (ie, SQL Compact will only run in WoW mode in x64 bits systems). So, if you also have a x64 version of an OS installed, don”t forget to explicitly set the build to x86 on the configuration of your project. One more thing you might notice after looking at the previous config entry is that I”m passing the special connection string to an attribute which is called connectionStringName. Well, if you want, you can pass it the name of an existing entry on the connectionString section instead (internally, the provider will try to get an existing entry named with the value you pass to the connectionStringName attribute. If it can”t find any, it will simply use the value you”ve passed to that atribute).

If you use reflector to check the code, you”ll see that the helper classes do have code that would let you use Isolated Storage for saving these data. However, there”s really no way to set it up (at least, I didn”t find any – maybe I”m missing something!) so you”ll have to choose between using the file system or a SQL compact database.

Before ending this post, there”s still one more thing you should keep in mind: you should always set the ConnectivityStatus.IsOffline property. If you explicitely set the property, then that value will be respected. If you don”t, then the value returned from the property will depend on the checking of a special file called AppIsOffline. This file is used as a marker and is created when you set the  the ConnectivityStatus.IsOffline property to true (notice that it will be deleted when you set the property to false). What this means is that if you”ve previously set that property to false and then don”t set it back to true, authentication will always be performed offline since that property will return true.

And that”s all for today…more to come tomorrow 🙂