Windows 凭据提供程序远程登录

Posted

技术标签:

【中文标题】Windows 凭据提供程序远程登录【英文标题】:windows credential provider remote logon 【发布时间】:2016-03-14 23:57:42 【问题描述】:

我正在尝试从一个工作站(本地)上的智能卡读取凭据,然后将其发送到不同的工作站(远程)并使用它从凭据提供程序中登录到该工作站。

我已经搜索并且研究了好几个星期,但没有找到任何人展示或告诉如何做到这一点。

我在https://www.idrix.fr/Root/Samples/LsaSmartCardLogon2.cpp 找到了几处对优秀作品的引用,它是智能卡凭据提供程序的工作代码,但不幸的是要求凭据提供程序可以直接访问带有凭据的智能卡。

我正在使用的实际代码似乎有点长,无法包含在帖子中,所以我想我尝试使用 sudo 代码来提问。 在本地工作站上:

MySendCredentialsFromSmartCard()
    CryptAcquireContext(hProv, containerName, cardName, PROV_RSA_FULL, CRYPT_SILENT) 
    CryptGetUserKey(*hProv, AT_KEYEXCHANGE, &hCryptKey); 
    CryptGetKeyParam(hCryptKey, KP_CERTIFICATE, encodedCert, &size, 0); 
    MySendCertToRemote(encodedCert,size); 
 

在自定义凭据提供程序中运行的远程工作站上:

HRESULT CSampleCredential::GetSerialization( 
    _Out_ CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *pcpgsr, 
    _Out_ CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcs, 
    _Outptr_result_maybenull_ PWSTR *ppwszOptionalStatusText, 
    _Out_ CREDENTIAL_PROVIDER_STATUS_ICON *pcpsiOptionalStatusIcon) 

    MyReadCertFromRemote(&cert,&size); 
    CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0); 
    CryptCreateHash(hCryptProv, CALG_SHA1, NULL, 0, &hHash); 
    CryptHashData(hHash, (BYTE *)cert, (DWORD)size, 0); 

    CERT_CREDENTIAL_INFO certInfo; 

    CryptGetHashParam(hHash, HP_HASHVAL, certInfo.rgbHashOfCert, &dwHashLen, 0); 
    CredMarshalCredential(CertCredential, &certInfo, marshalledCred); 
/****************************for debug only*****************************/ 
    LogonUser((*marshalledCred, NULL, NULL, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, &userHandle); 
//this reuturns 1 (success) 
/**************************************************************************/ 
    KERB_INTERACTIVE_UNLOCK_LOGON kiul; 
    CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus 
    KerbInteractiveUnlockLogonInit(L"", (PWSTR)marshaledCred, L"", cpus, &kiul);//(note:I've tried this with the third param set to the card's pin) 
    KerbInteractiveUnlockLogonPack(kiul, &pcpcs->rgbSerialization, &pcpcs->cbSerialization); 
    RetrieveNegotiateAuthPackage(&ulAuthPackage); 
    pcpcs->ulAuthenticationPackage = ulAuthPackage; 
    pcpcs->clsidCredentialProvider = CLSID_OfProvider; 
    *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED; 
 

LogonUI.exe 显示“指定的登录会话不存在。它可能已经终止。”此接缝对应于 Windows 错误代码 1312。似乎大多数处理此错误代码的开发人员在使用 SSL 证书配置 IIS 时遇到问题。我没有发现与凭据提供程序有关的此错误的参考。 各种线程似乎表明 LogonUser 只是 LSALogonUser 的包装器,并且来自 ICredentialProviderCredential::GetSerialization 的返回值将传递给 LSALogonUser。我使用编组凭据成功调用 LogonUser 的事实似乎表明我走在正确的轨道上,但我无法验证这一点,也无法弄清楚我错过了什么。 我想尽量避免需要将凭据存储在远程工作站上的解决方案,因为它通常是域管理员凭据。 有什么想法吗?关于如何进行的任何建议?

谢谢

【问题讨论】:

【参考方案1】:

我想你可以使用一种通信机制来做到这一点,你将数据从一个工作站发送到另一个工作站,然后在远程工作站中,你在 SetSerialization() 而不是 GetSerialization() 中序列化数据,准备所有字段并处理登录。

根据我对您的理解,Provider 类(由 ICredentialProvider 继承的)必须以某种方式等待这些凭据并将它们传递给 SetSerialization

【讨论】:

以上是关于Windows 凭据提供程序远程登录的主要内容,如果未能解决你的问题,请参考以下文章

从通过 Windows 凭据 (Kerberos) 登录的用户生成 OAuth2 令牌

远程桌面连接输入用户名和密码以后提示“您的凭据不工作”无法登陆

解决WIN7远程登录提示无法保存凭据的问题

Laravel:针对远程检查凭据的系统进行身份验证

失败后停止自动登录 - 自定义凭据提供程序 Windows

win10远程凭据无法工作怎么解决