【问题标题】:Provide Credential Information from Credential Provider to C# Service将凭据信息从凭据提供程序提供给 C# 服务
【发布时间】:2015-05-03 19:00:09
【问题描述】:

我写了一个自定义的Windows Credentials Provider 来捕获用户登录。此提供程序的主要目的之一是存储用户的密码,并在登录时在 Windows 上运行的 C# 服务中使用它。

这让我想到了在哪里以及如何存储凭证信息的问题。在登录时(即用户提供有效的登录信息并选择登录)服务应该能够获取信息并使用它。

将凭证信息传达给服务的正确方法是什么?

使用凭据登录用户的部分或多或少根据为凭据提供程序提供的 Microsoft 示例,其中 GetSerialization 如下所示:

hr = ProtectIfNecessaryAndCopyPassword(_rgFieldStrings[SFI_PASSWORD], _cpus, &pwzProtectedPassword);

g_pwzProtectedPassword = pwzProtectedPassword;

if (SUCCEEDED(hr))
{
    PWSTR pszDomain;
    PWSTR pszUsername;
    hr = SplitDomainAndUsername(_pszQualifiedUserName, &pszDomain, &pszUsername);
    if (SUCCEEDED(hr))
    {
        KERB_INTERACTIVE_UNLOCK_LOGON kiul;
        hr = KerbInteractiveUnlockLogonInit(pszDomain, pszUsername, pwzProtectedPassword, _cpus, &kiul);
        if (SUCCEEDED(hr))
        {
            // We use KERB_INTERACTIVE_UNLOCK_LOGON in both unlock and logon scenarios.  It contains a
            // KERB_INTERACTIVE_LOGON to hold the creds plus a LUID that is filled in for us by Winlogon
            // as necessary.
            hr = KerbInteractiveUnlockLogonPack(kiul, &pcpcs->rgbSerialization, &pcpcs->cbSerialization);
            if (SUCCEEDED(hr))
            {
                ULONG ulAuthPackage;
                hr = RetrieveNegotiateAuthPackage(&ulAuthPackage);
                if (SUCCEEDED(hr))
                {
                    pcpcs->ulAuthenticationPackage = ulAuthPackage;
                    pcpcs->clsidCredentialProvider = CLSID_CredentialProvider;
                    // At this point the credential has created the serialized credential used for logon
                    // By setting this to CPGSR_RETURN_CREDENTIAL_FINISHED we are letting logonUI know
                    // that we have all the information we need and it should attempt to submit the
                    // serialized credential.
                    *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
                }
            }
        }
        CoTaskMemFree(pszDomain);
        CoTaskMemFree(pszUsername);
    }
    CoTaskMemFree(pwzProtectedPassword);
}

编辑:

我尝试使用 Windows 凭据管理器 API 来保存密码,但这似乎没有效果。当我尝试获取登录后的用户名/密码时,我什么也没有返回。

DWORD cbCreds = (DWORD)(1 + strlen(password));

CREDENTIALW cred = { 0 };
cred.Type = CRED_TYPE_GENERIC;
cred.TargetName = TargetName;
cred.CredentialBlobSize = cbCreds;
cred.CredentialBlob = (LPBYTE)password;
cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
cred.UserName = *username;

return ::CredWriteW(&cred, 0) ? true : false;

【问题讨论】:

    标签: c++ windows com password-protection credential-providers


    【解决方案1】:

    认为管道是与服务通信的正确方式。 并且使用 Windows Credential Manager 保存/加载密码无效,因为登录会话不同,并且用户的 SID 在尚未登录时被禁用。

    【讨论】:

    • 没有比自己存储用户名/密码组合更安全的方法吗?我希望 Windows 会解决这个问题 - 在成功的初始化之后。更重要的是:如果用户更改了他的原始密码,我存储的密码将失效。内置 PIN CP 可以更智能地处理此问题。
    猜你喜欢
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多