CredRead() not working across login sessions

2019-07-01 17:51发布

问题:

I am using the Credential Manager API as per this answer. Quoting relevant code snippet:

public static Credential ReadCredential(string applicationName)
{
    IntPtr nCredPtr;
    bool read = CredRead(applicationName, CredentialType.Generic, 0, out nCredPtr);
    if (read)
    {
        using (CriticalCredentialHandle critCred = new CriticalCredentialHandle(nCredPtr))
        {
            CREDENTIAL cred = critCred.GetCredential();
            return ReadCredential(cred);
        }
    }

    return null;
}

It works great, except that when I log off my Windows account and then login again, CredRead() returns false and Marshal.GetLastWin32Error() gives me 1168, or ERROR_NOT_FOUND.

Why this behaviour? Does the Credential Management API work only for the current session, or am I doing something wrong?

Edit: A comment beneath this question says that:

The documents for the credential management APIs seem to indicate that these credentials are associated with a logon session. Perhaps LogonUser results in a new logon session, so the credentials don't exist there.

However I haven't yet found any evidence that Credential Management is session-specific. I think it would be pretty useless if that were the case.

Edit 2: Just for the record, if you need to get the error number indicating why CredRead() is failing, check ReadCred() method in this article.

回答1:

You can configure how the credential is persisted by setting the Persist property

From MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx)

CRED_PERSIST_SESSION
CRED_PERSIST_LOCAL_MACHINE
CRED_PERSIST_ENTERPRISE