How to prompt for a password on Windows?
This post is part of the series 'Password management'. Be sure to check out the rest of the blog posts of the series!
- How to store a password in a web application?
- How to implement Password reset feature in a web application?
- How to store a password on Windows?
- How to prompt for a password on Windows? (this post)
- Helping users to create good passwords
- Automatically log in a user on a website using the Credential Management API?
- How to avoid storing secrets in the source code?
In the previous post, we discovered how to store a password on Windows using the Credential Manager. Today, we'll see the other part of the API which allows the user to enter their password. This API allows asking for a username/password for a console application or a GUI application. Optionally, they can save the password in the Credential Manager, so the next time the passwords are read directly from the Credential Manager instead of prompting the user.
Credential Manager GUI demo
#Console application
Asking for a password in a console application is not easy. It requires to mask the data when the user enters it. It means you have to intercept keys using Console.ReadKey
and handle it correctly. Or you can use the function CredUICmdLinePromptForCredentials
.
Instead of writing your own wrapper, you can use the NuGet package Meziantou.Framework.Win32.CredentialManager
(NuGet, GitHub)
// Requires NuGet Meziantou.Framework.Win32.CredentialManager
using System;
using Meziantou.Framework.Win32;
internal class Program
{
private static void Main(string[] args)
{
var creds = CredentialManager.PromptForCredentialsConsole(target: "https://www.meziantou.net");
Console.WriteLine($"User: {creds?.UserName}, Password: {creds?.Password}, Domain: {creds?.Domain}");
}
}
You can set an optional username, so the user will only have to enter their password.
// Requires NuGet Meziantou.Framework.Win32.CredentialManager
using System;
internal class Program
{
private static void Main(string[] args)
{
var creds = CredentialManager.PromptForCredentialsConsole(
target: "https://www.meziantou.net",
saveCredential: CredentialSaveOption.Hidden,
userName: "Meziantou"
);
Console.WriteLine($"User: {creds?.UserName}, Password: {creds?.Password}, Domain: {creds?.Domain}");
}
}
PromptForCredentialsConsole demo
#Desktop application
In a desktop application, you can use a PasswordBox
to ask for the user to enter their password. However, you have to design the login window for your application. The Credential Manager comes with a default UI that allows you to prompt for credentials: CredUIPromptForWindowsCredentials
.
Instead of writing your own wrapper, you can use the NuGet package Meziantou.Framework.Win32.CredentialManager
(NuGet, GitHub)
// Requires NuGet Meziantou.Framework.Win32.CredentialManager
using System;
internal class Program
{
private static void Main(string[] args)
{
var creds = CredentialManager.PromptForCredentials(
target: "https://www.meziantou.net",
captionText: "https://www.meziantou.net",
messageText: "This will allow SampleApp to authenticate to Meziantou's blog",
saveCredential: CredentialSaveOption.Selected
//userName: "Meziantou" // Pre-fill the UI with a default username
);
Console.WriteLine($"User: {creds?.UserName}, Password: {creds?.Password}, Domain: {creds?.Domain}");
}
}
Credential Manager GUI demo
#UWP application
UWP comes with its wrapper of the Credential Manager API. So, you don't need any code nor third-party libraries to use it. It's available through the CredentialPicker
class:
<Page
x:Class="SampleCredentialPicker.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Button Click="Button_Click">Login</Button>
</Grid>
</Page>
using System;
using Windows.Security.Credentials.UI;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace SampleCredentialPicker
{
public sealed partial class MainPage : Page
{
public MainPage() => InitializeComponent();
private async void Button_Click(object sender, RoutedEventArgs e)
{
var options = new CredentialPickerOptions()
{
TargetName = "https://www.meziantou.net",
Caption = "https://www.meziantou.net",
Message = "This will allow SampleApp to authenticate to Meziantou's blog",
CredentialSaveOption = CredentialSaveOption.Selected,
AuthenticationProtocol = AuthenticationProtocol.Basic, // Allows to get the clear password
};
CredentialPickerResults result = await CredentialPicker.PickAsync(options);
var dialog = new MessageDialog($"User: {result.CredentialUserName}, Password: {result.CredentialPassword}, Domain: {result.CredentialDomainName}");
await dialog.ShowAsync();
}
}
}
UWP - CredentialPicker
Do you have a question or a suggestion about this post? Contact me!