Using the Credential Management API

Page 2 of 2
  1. Wrapper Code
  2. Using the CredentialsDialog class

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.

You might also like...

Comments

Alan Dean I am a UK-based professional software developer. I am also active in the development user community.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Linux is only free if your time has no value” - Jamie Zawinski