C#でWindows資格情報に登録されているか確認する方法

業務でWindows資格情報を読む機能を実装したことがあったので備忘録として残す。

WindowsAPIのCredRead関数をC#から呼び出すことで実装可能。
サンプルコードは以下。

[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool CredRead(string target, uint type, int reservedFlag, out IntPtr credentialPtr);

[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
private static extern bool CredFree(IntPtr cred);

private enum CredType
{
    GENERIC = 1,
    DOMAIN_PASSWORD = 2,
    DOMAIN_CERTIFICATE = 3,
    DOMAIN_VISIBLE_PASSWORD = 4,
    MAXIMUM = 5
}

/// <summary>
/// 資格情報マネージャーに登録されているかどうかをチェックする
/// </summary>
/// <param name="target">資格情報の名前</param>
/// <returns>登録されているかどうか(true:登録済み、false:未登録)</returns>
private static bool CheckCredential(string target)
{
    IntPtr handle = IntPtr.Zero;
    bool result = false;
    try
    {
        result = CredRead(target, (int)CredType.DOMAIN_PASSWORD, 0, out handle);
    }
    finally
    {
        if (handle != IntPtr.Zero)
        {
            CredFree(handle);
        }
    }
    return result;
}

DllImportを使うので、using System.Runtime.InteropServices;の追加も忘れなく。

例えばWindows資格情報に以下の画像のように登録されているかどうかチェックしたい場合

f:id:powerbombkun:20211223132700p:plain
Windows資格情報サンプル

CheckCredentialメソッドの呼び出し側で以下のように実装する。

string target = "myserver";
bool result = CheckCredential(target);
if (result)
{
    Console.WriteLine(target + "は登録されています。");
}