将凭据从应用转发到凭据提供者

时间:2019-07-10 14:23:03

标签: c++ windows credentials credential-providers

我已经开始研究凭证提供者的工作方式,但是由于文档不完善,我陷入了很多困境。

当我远程连接到该应用程序并进行身份验证(没有登录)时,我具有控制台应用程序(类似于ssh服务器),我希望它能够将那些凭据转发到凭据提供者,并且我希望CP登录用户(创建会话)。

我还注意到在文档中它说SetSerialization方法总是在SetusageScenario之后被调用。但是我添加了日志,SetSerialization从未在SetusageScenario之后被调用。

据我所知,当应用程序提供凭据时会调用SetSerialization。我不明白通过应用程序提供证书意味着什么?将凭据从应用程序转发到凭据提供者似乎是我所需要的,但是我该怎么做呢?我可以从凭证提供者dll调用某些功能来引发登录吗?

有什么办法可以实现?我已经读到,完成远程登录后,将调用UpdateRemoteCredential,但是据我了解(如果我错了,请纠正我)在远程登录中意味着RDP,但我的应用程序很简单,它只是侦听某个端口并获取用户名和密码,然后使用Logonuser函数。

名为MxLogon2的程序实现了该方案。安装了MxLogon2的远程服务器可以验证在远程桌面会话中连接到客户端的USB密钥(但我想要用户名/密码)。

任何将我引向正确方向的建议都会被采纳。

PS

我正在使用pGina作为凭据提供者。

1 个答案:

答案 0 :(得分:0)

在您的情况下,我不太介意SetSerialization。用于预初始化图块。

一个示例是,通过RDP连接,您可以在系统上存储凭据证书。此功能用于预先查询具有这些凭据的磁贴(虽然不是唯一的解决方案)。

根据您的情况让它返回E_NOTIMPL。

提供程序的主要目的是初始化凭据和图块:

  1. 凭据初始化

通过SetUsageScenario函数完成(在Provider构建之后自动调用)。 在其中,您可以根据所处的场景自定义行为。最基本的一种是CPUS_LOGON。 看起来像这样(这只是预览)

HRESULT Provider::SetUsageScenario(
__in CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
__in DWORD dwFlags
)
{
    HRESULT hr;

    switch(cpus)
    {
        case CPUS_UNLOCK_WORKSTATION:
        case CPUS_LOGON:
        hr = this->_InitCredential();
        break;

        default:
        hr = E_INVALIDARG;
        break;
    }

    return hr;
}
  1. 瓷砖初始化

开始于GetCredentialCount函数。它允许您定义要显示多少个图块(pdwCount out参数),以及用作默认图块的图块(pdwDefault)。 自动登录也可以在这里处理(通过pbAutoLogonWithDefault)。

然后在GetCredentialAt函数中开始枚举枚举。

通过GetSerialization函数在使用的凭据中完成身份验证的传递凭据。

可以在here中找到实现示例。 我几乎不坚持使用示例,因为它很容易根据您要实现的目标而转移。这是非常灵活的,您最好了解任何功能/参数的目的以适合您的目标。

编辑-cf评论:

#define IDCredential        0x1

Credential::Credential(Provider* parent)
{
    //Do ssh connection or whatever

    if(success)
    {
        parent->login = retrievedLogin;
        parent->pwd = retrievedPwd;
        parent->CredentialUsed = IDCredential;
        parent->autoLogin = true;
        parent->ProviderEvents->CredentialsChanged(AdviseContext);
    }
}

HRESULT Provider::GetCredentialCount(
    __out DWORD* pdwCount,
    __out_range(<,*pdwCount) DWORD* pdwDefault,
    __out BOOL* pbAutoLogonWithDefault
    )
{
    if(this->autoLogin && this->CredentialUsed)
    {
        *pbAutoLogonWithDefault = true; // --> Instant call to GetSerialization
        *pdwDefault = this->CredentialUsed; //index of the tile
    }
    else
    {
        *pbAutoLogonWithDefault = false;
        *pdwDefault = IDCredential;
    }

    return S_OK;
}