自定义凭据提供者:如何向后续创建的登录会话传递数据?
向Windows登录会话传递自定义凭据提供者数据的方法
核心实现路径
Windows凭据提供者的ICredentialProviderCredential::GetSerialization方法确实支持向后续登录会话传递额外数据,主要通过以下几种可靠方式实现:
1. 扩展Kerberos/NTLM序列化结构体
如果你的凭据提供者基于Kerberos或NTLM认证流程,可以在标准登录结构体中嵌入自定义数据:
- 在
GetSerialization中构造KERB_S4U_LOGON或对应登录类型的结构体时,将额外数据(如令牌序列号)追加到结构体的末尾作为扩展区域。 - 系统会将完整的序列化数据传递给LSASS(本地安全授权子系统服务),登录成功后,可通过以下方式获取:
- 调用
LsaGetLogonSessionData获取当前会话的登录信息,解析其中的AuthenticationPackageData字段提取自定义数据。 - 编写专用Windows服务,通过LSASS的接口读取会话关联的扩展数据。
- 调用
2. 实现自定义LSA认证包
如果硬件认证逻辑完全独立于现有协议,自定义认证包是最灵活的方案:
- 开发符合LSA接口规范的自定义认证包(实现
LsaApInitializePackage、LsaApLogonUser等核心接口),在认证包中处理凭据提供者传递的序列化数据。 - 在
GetSerialization中,将额外数据写入CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION的rgbSerialization缓冲区,指定自定义的dwAuthenticationPackageID。 - 自定义认证包在处理登录请求时,将额外数据绑定到登录会话上下文,后续进程可通过
LsaCallAuthenticationPackage调用自定义接口获取数据。
3. 临时存储方案(仅适用于测试场景)
如果对安全隔离要求不高,可临时将数据写入加密的临时文件或当前会话的注册表项:
- 注意:该方式存在数据泄露风险,其他进程可能访问到存储内容,仅用于快速验证。
- 登录后的应用读取数据后需立即删除,避免残留敏感信息。
关键代码示例(扩展KERB_S4U_LOGON)
HRESULT CSampleCredential::GetSerialization( CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr, CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs, PWSTR* ppwszOptionalStatusText, CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon ) { // 初始化Kerberos S4U登录结构体 KERB_S4U_LOGON s4uLogon = {0}; s4uLogon.MessageType = KerbS4ULogon; // 填充用户名、域名等必要登录字段... // 嵌入自定义令牌序列号 DWORD tokenSerial = 0x12345678; size_t totalSize = sizeof(KERB_S4U_LOGON) + sizeof(DWORD); PBYTE pSerializedData = (PBYTE)malloc(totalSize); memcpy(pSerializedData, &s4uLogon, sizeof(KERB_S4U_LOGON)); memcpy(pSerializedData + sizeof(KERB_S4U_LOGON), &tokenSerial, sizeof(DWORD)); // 设置序列化响应参数 pcpcs->rgbSerialization = pSerializedData; pcpcs->cbSerialization = totalSize; pcpcs->ulAuthenticationPackage = AUTH_PACKAGE_KERBEROS; *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED; return S_OK; }
重要注意事项
- 所有敏感数据必须加密后传递,避免明文暴露在序列化缓冲区中。
- 自定义认证包需进行数字签名并注册到系统,否则LSASS会拒绝加载。
- 登录会话结束后,务必清理所有临时存储的数据和内存,防止泄漏或残留。
内容的提问来源于stack exchange,提问作者Ratlos
相关产品推荐
相关产品推荐

