次の方法で共有


Windows アプリの資格情報ロッカー

この記事では、Windows アプリで資格情報保管ボックスを使用して、ユーザーの資格情報を安全に保存および取得し、ユーザーの Microsoft アカウントを使用してデバイス間でローミングする方法について説明します。

Credential Locker アクセス用の Windows ランタイム (WinRT) API は、Windows ソフトウェア開発キット (SDK)の一部です。 これらの API は、WinUI だけでなく、WPF や WinForms などの他のデスクトップ アプリでも使用できます。 Windows デスクトップ アプリで WinRT API を使用する方法の詳細については、「デスクトップ アプリでの Call Windows ランタイム API」を参照してください

サンプル シナリオの概要

たとえば、メディア ファイルやソーシャル ネットワークなど、保護されたリソースにアクセスするサービスに接続するアプリがあるとします。 サービスには、ユーザーごとにログイン情報を渡す必要があります。 ユーザーのユーザー名とパスワードを取得する UI をアプリに組み込み、ユーザーをサービスにログインさせるために使用します。 Credential Locker API を使うと、ユーザーのユーザー名とパスワードを格納し、次回のアプリの実行時に取得してデバイスを問わずユーザーを自動的にログインさせることができます。

資格情報ロッカーに格納されているユーザー資格情報は期限切れになりません。ApplicationData.RoamingStorageQuotaの影響を受けません。従来のローミング データのような非アクティブのため消去されません。 ただし、資格情報ロッカーには、アプリごとに最大 20 個の資格情報のみを格納できます。

資格情報ロッカーは、ドメイン アカウントの動作が少し異なります。 Microsoft アカウントと共に格納された資格情報がある場合、そのアカウントをドメイン アカウント (職場で使うアカウントなど) に関連付けると、資格情報はドメイン アカウントにローミングされます。 ただし、ドメイン アカウントでのサインオン中に追加された新しい資格情報はローミングされません。 これにより、ドメインのプライベート資格情報がドメインの外部に公開されないようにします。

ユーザー資格情報の格納

  1. Windows.Security.Credentials 名前空間の PasswordVault オブジェクトを使って、資格情報保管ボックスへの参照を取得します。
  2. PasswordCredential オブジェクトを作成し、アプリの識別子、ユーザー名、パスワードを含めます。これを PasswordVault.Add メソッドに渡して、資格情報を保管ボックスに追加します。
var vault = new Windows.Security.Credentials.PasswordVault();
vault.Add(new Windows.Security.Credentials.PasswordCredential(
    "My App", username, password));

ユーザー資格情報の取得

PasswordVault オブジェクトへの参照を取得した後、資格情報保管ボックスからユーザー資格情報を取得するには、いくつかの方法があります。

  • PasswordVault.RetrieveAll メソッドを使うと、ユーザーからアプリに提供された保管ボックス内の資格情報をすべて取得できます。
  • 格納されている資格情報のユーザー名がわかっている場合は、PasswordVault.FindAllByUserName メソッドを使うことで、そのユーザー名の資格情報をすべて取得できます。
  • 格納されている資格情報のリソース名がわかっている場合は、PasswordVault.FindAllByResource メソッドを使うことで、そのリソース名の資格情報をすべて取得できます。
  • 最後に、資格情報のユーザー名とリソース名の両方がわかっている場合は、PasswordVault.Retrieve メソッドを使うことで、該当する資格情報だけを取得できます。

例を見てみましょう。次の例では、リソース名をアプリ内でグローバルに格納し、ユーザーの資格情報が見つかった場合に、そのユーザーとして自動的にログインします。 同じユーザーに対して複数の資格情報がある場合は、ログオンに使う既定の資格情報をユーザーに選んでもらいます。

private string resourceName = "My App";
private string defaultUserName;

private void Login()
{
    var loginCredential = GetCredentialFromLocker();

    if (loginCredential != null)
    {
        // There is a credential stored in the locker.
        // Populate the Password property of the credential
        // for automatic login.
        loginCredential.RetrievePassword();
    }
    else
    {
        // There is no credential stored in the locker.
        // Display UI to get user credentials.
        loginCredential = GetLoginCredentialUI();
    }

    // Log the user in.
    ServerLogin(loginCredential.UserName, loginCredential.Password);
}

private Windows.Security.Credentials.PasswordCredential GetCredentialFromLocker()
{
    Windows.Security.Credentials.PasswordCredential credential = null;

    var vault = new Windows.Security.Credentials.PasswordVault();

    IReadOnlyList<PasswordCredential> credentialList = null;

    try
    {
        credentialList = vault.FindAllByResource(resourceName);
    }
    catch(Exception)
    {
        return null;
    }

    if (credentialList.Count > 0)
    {
        if (credentialList.Count == 1)
        {
            credential = credentialList[0];
        }
        else
        {
            // When there are multiple usernames,
            // retrieve the default username. If one doesn't
            // exist, then display UI to have the user select
            // a default username.
            defaultUserName = GetDefaultUserNameUI();

            credential = vault.Retrieve(resourceName, defaultUserName);
        }
    }

    return credential;
}

ユーザー資格情報の削除

資格情報保管ボックスからのユーザー資格情報の削除も、2 段階のプロセスで簡単に行うことができます。

  1. Windows.Security.Credentials 名前空間の PasswordVault オブジェクトを使って、資格情報保管ボックスへの参照を取得します。
  2. 削除する資格情報を PasswordVault.Remove メソッドに渡します。
var vault = new Windows.Security.Credentials.PasswordVault();
vault.Remove(new Windows.Security.Credentials.PasswordCredential(
    "My App", username, password));

ベスト プラクティス

資格情報保管ボックスはパスワードのみに使い、大きいデータ BLOB には使わないようにします。

次の条件が満たされている場合にのみ、資格情報保管ボックスにパスワードを保存します。

  • ユーザーが正常にサインインしている。
  • ユーザーがパスワードの保存を選んでいる。

アプリ データまたはローミングの設定を使って資格情報をプレーンテキストに格納しないでください。