We need you!

We're working hard on the next version of Developer Fusion. Let us know what you think we should be up to!

Members

Technology Zones

Articles

Hosted By

MaximumASP

Info

Rated
Read 24,002 times

Contents

Related Categories

Using the Credential Management API - Using the CredentialsDialog class

alan.dean

Using the CredentialsDialog class

Default Mode

This example uses all the defaults to present an application gatekeeper dialog that will store the credentials. In the majority of situations, these defaults will meet your needs. The only value that must be set in all cases is the Target.

using System;
using System.Windows.Forms;
using SecureCredentialsLibrary;
namespace SecureCredentialsApplication
{
    public class App
    {
        [STAThread] static void Main()
        {
            if (Login(null)) Application.Run(new Form1());
        }
       
        private static bool Login(string name)
        {
            bool value = false;
            try
            {
                CredentialsDialog dialog = new CredentialsDialog("Secure Application");
                if (name != null) dialog.AlwaysDisplay = true; // prevent an infinite loop
                if (dialog.Show(name) == DialogResult.OK)
                {
                    if (Authenticate(dialog.Name, dialog.Password))
                    {
                        value = true;
                        if (dialog.SaveChecked) dialog.Confirm(true);
                    }
                    else
                    {
                        try
                        {
                            dialog.Confirm(false);
                        }
                        catch (ApplicationException applicationException)
                        {
                            // exception handling ...
                        }
                        value = Login(dialog.Name); // need to find a way to display 'Logon unsuccessful'
                    }
                }
            }
            catch (ApplicationException applicationException)
            {
                // exception handling ...
            }
            return value;
        }
       
        private static bool Authenticate(string name, string password)
        {
            // return true if the authentication succeeds
        }
    }
}

 

The first time that the dialog is displayed the name / password contain no text and the message is "Welcome to ...":

The dialog displayed when no credentials have been stored.

When the user provides an authentic name / password and checks "Remember my password" the credentials are stored:

The dialog displayed when no credentials have been stored.

On subsequent calls, the dialog will not be displayed if the credentials are still authentic. If the credentials are not authenticated, then the dialog will prompt the user for new credentials. This is the behaviour that most users normally expect (note that the message now is "Welcome back to ...", which is a nice touch):

The dialog displayed when no credentials have been stored.

Fixed Name Mode

This example presents an application gatekeeper dialog that will store the credentials but has a read-only name. This is an appropriate mode for certain situations, for example providing specific role credentials such as logging on as an owner.

          ...
        [STAThread] static void Main()
        {
            if (Login("Owner")) Application.Run(new Form1());
        }
       
        private static bool Login(string name)
        {
            bool value = false;
            try
            {
                CredentialsDialog dialog = new CredentialsDialog("Secure Application");
                dialog.KeepName = true;
                ...

 

The dialog will now only accept the password (note that the user cannot save the password in this mode, so the dialog will always be displayed):

The dialog displayed when no credentials have been stored.

Application Manager Mode

This example stops the credential manager from persisting the credentials. This means that your application must take on the responsibility for persisting the data, if you want to. There are also situations when you may not want to persist credentials at all.

...
        [STAThread] static void Main()
        {
            if (Login()) Application.Run(new Form1());
        }
       
        private static bool Login()
        {
            bool value = false;
            try
            {
                CredentialsDialog dialog = new CredentialsDialog("Secure Application");
                dialog.AlwaysDisplay = true;
                dialog.Persist = false;
                if (dialog.Show(StoredName(), StoredPassword()) == DialogResult.OK)
                {
                    if (Authenticate(dialog.Name, dialog.Password))
                    {
                        value = true;
                        if (dialog.SaveChecked) Store(dialog.Name, dialog.Password);
                    }
                    else
                    {
                        try
                        {
                            Store(dialog.Name, null);
                        }
                        catch (ApplicationException applicationException)
                        {
                            // exception handling ...
                        }
                        value = Login(); // need to find a way to display 'Logon unsuccessful'
                    }
                }
            ...
       
        private static string StoredName()
        {
            // return the name (if stored)
        }
       
        private static string StoredPassword()
        {
            // return the password (if stored)
        }
       
        private static void Store(string name, string password)
        {
            // store the credentials (if supported)
        }

The dialog will now display the specified name / password (note that the user cannot save the password in this mode, so the save checkbox is not available):

The dialog displayed when no credentials have been stored.

Styling

This example shows how the dialog display can be amended. I personally think that normally it would be better to stay with the default display for consistency but the API supports changing the display, so here you are:

        ...
       
        private static bool Login(string name)
        {
            bool value = false;
            try
            {
                CredentialsDialog dialog = new CredentialsDialog("Secure Application");
                dialog.Caption = "A caption";
                dialog.Message = "A message";
                dialog.Banner = System.Drawing.Image.FromFile(@"{an image filename}");
                ...

You can display an opaque image, or a gif with transparency set:

The dialog displayed when no credentials have been stored.

... and that's all folks!

To Do List

These tasks are outstanding (any feedback would be appreciated):

  • To get the CREDUI_FLAGS_INCORRECT_PASSWORD flag to operate (or to understand why it doesn't seem to operate).
  • To understand why the CredUIConfirmCredentials call returns ERROR_INVALID_PARAMETER when credentials are overwritten.
  • To run the dialog under MUI (multilanguage user interfaces) to identify if the CREDUI is a fully globalized library.
  • To understand why the persisted credentials are not visible on the "Stored User Names and Passwords" dialog (via Control Panel > User Accounts).
  • To research how to use the SecureString class from Framework 2.0 to secure the credentials in memory.

Comments

  • Re: Credentials not being saved

    Posted by dcomer on 24 Jun 2008

    Not sure if Jim will see this due to the time lapse, but I have also see the same issue. I believe I've narrowed it down to a race condition that occurs between the time the

  • Save Credentials in Stored User Names and Password

    Posted by billyana on 09 Jan 2006

    Alan:

    First of all thank you for posting this code.

    The credetials get stored in Stored User Names and Passwords if flag CREDUI_FLAGS_GENERIC_CREDENTIALS (or CREDUI.FLAGS.GENERIC_CREDENTIALS) is...

  • Credentials not being saved

    Posted by james.hotchkiss on 20 Jul 2005

    Hi, I've noticed the first time I run this it seems to return without error on the Confirm Credentials part, but Credentials are not appearing in the User Credential Manager and I can't actually acces...