Once the client application services are enabled, you can
configure what type of authentication to use. For the sake of this article,
Forms authentication will be used. Once the radio button Use Forms
Authentication is selected, you should provide the remote authentication
service location. In this case it is the URL for the ASP.NET website host
application that was created in a previous section of this article. When it is
time to access the remote authentication service, the Client Application
Services framework adds the Authenticate_JSON_AppService.axd to the configured
URL. This is the URL for the HttpHandler that will access the configured
Membership provider set by the ASP.NET website host application.
The next entry to set is the Credentials provider. As
mentioned in part 1 of this article, this should point to the Login form that
will be used to gather credentials from the user to authenticate against the
remote authentication service. As we will see soon, the Login form will
implement the IClientFormsAuthenticationCredentialsProvider interface and
provide code for the GetCredentials method. This method will be called when you
issue a call to the Membership.ValidateUser method later in the application.
Finally, you should set the URL for the Roles service. The
same URL will be used here and again, the Client Application Service framework
will append to the URL the Role_JSON_AppService.axd HttpHandler path that will
be used to access the remote Roles service.
Now that the Client Application Service is enabled, it is time
to create the Login form. We do this by adding a new Windows Form called
Login.cs. This form, as mentioned before, should implement the
IClientFormsAuthenticationCredentialsProvider interface and provide a method
called GetCredentials that will return an instance of
ClientFormsAuthenticationCredentials object filled with the credentials entered
by the user. The implementation of the form is quiet simple and is shown below.
Listing 3
namespace ClientApplication
{
public partial class Login: Form,
IClientFormsAuthenticationCredentialsProvider
{
public Login()
{
InitializeComponent();
}
#region IClientFormsAuthenticationCredentialsProvider Members
public ClientFormsAuthenticationCredentials GetCredentials()
{
if (this.ShowDialog() == DialogResult.OK)
{
return new ClientFormsAuthenticationCredentials(this.txtUsername.Text,
this.txtPassword.Text, false);
}
else
{
return null;
}
}
#endregion
}
}
You can see how simple it is with the implementation of the
GetCredentials method. It shows the Login form and waits for the OK button to
be clicked, and then it returns an instance of the
ClientFormsAuthenticationCredentials containing the credentials entered by the
user.
After developing the Login form, we will create the main
applications’ form. In the Form_Load event of this form, we will issue a call
to validate the user as shown below.
Listing 4
private void Form1_Load(object sender, EventArgs e)
{
// Validate the user
if (!ValidateUser())
return ;
// Fill user information
DisplayUserInfo();
}
private bool ValidateUser()
{
bool isAuthenticated = false;
try
{
isAuthenticated = Membership.ValidateUser(string.Empty, string.Empty);
}
catch (System.Net.WebException ex)
{
// a WebException is raised when the authentication service
// cannot be reached
if (DialogResult.OK == MessageBox.Show(
"Unable to access the authentication service", "Not logged in",
MessageBoxButtons.OK, MessageBoxIcon.Error))
Application.Restart();
}
if (!isAuthenticated)
{
MessageBox.Show("Unable to authenticate credentials", "Not logged in",
MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
return isAuthenticated;
}
In the Form_Load event there is a call to ValidateUser
method which calls the Membership.ValidateUser method. Calling this method with
empty string is a must so that the credentials login form pops up.
If the authentication service is unavailable, then a
System.Net.WebException is thrown. If ValidateUser method returns true, the
current user is now authenticated and an authentication cookie is now created
for the user on the local hard disk.
In addition, there is a call for the method DisplayUserInfo.
This method shall bind a label on the main form to some information about the
user, mainly a welcome message, and display the authentication type.
Listing 5
private void DisplayUserInfo()
{
// Get the ClientFormsIdentity
ClientFormsIdentity user = (ClientFormsIdentity)
System.Threading.Thread.CurrentPrincipal.Identity;
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Welcome {0} !! \r\n\r\n" + "Authentication Type: {1} \r\n",
user.Name, user.AuthenticationType);
this.label1.Text = sb.ToString();
}
Notice how we are retrieving an instance of the
ClientFormsIdentity by casting the Identity property on the
System.threading.Thread.CurrentPrincipal object.