CredentialProvider交互式登录实现
前言:个人在开发CredentialProvider登录插件不可避免的会有登录交互需求,如指纹登录验证时提示用户按压指纹、人脸识别登录时提示用户居中人脸等,而默认的ICredentialProviderCredential接口在点击登录按钮(CPFT_SUBMIT_BUTTON)后直接调用GetSerialization方法进行登录验证,验证成功后直接反馈最终的登录结果,若直接在GetSerialization方法实现的最前面加入自定义交互代码可行吗?表示经测试不可行,个人在GetSerialization方法前加入过对自定义登录插件中CPFT_LARGE_TEXT控件文本的修改操作,但在用户点击提交按钮后登录界面会跳转至“登录验证等待界面”,如下图所示,即自定义CredentialProvider登录插件中所定义的UI在点击提交按钮后被显示的的“验证等待界面”隐藏了,故设置的CPFT_LARGE_TEXT控价的文本值无法被看到,只能说CredentialProvider接口太死板了,有些不符合大众人的思路逻辑,但CredentialProvider不能实现交互式登录操作了吗?答案当然是否定的,微软对此提供了单独的接口让开发者进行自定义处理,本文将对此进行讲述。

交互式登录实现方法:对于交互式登录,CredentialProvider接口提供了一个单独的接口类进行处理,接口类为IConnectableCredentialProviderCredential,实现方法自定义凭据对象继承下该接口类并实现Connnect方法,该方法在GetSerialization方法之前执行,方法传入一个IQueryContinueWithStatus* pqcws参数,通过该参数用户可以根据自定义登录插件交互需要设置交互提示信息,在Connect函数执行过程中界面会显示一个“取消”按钮,用户在登录验证过程中可以随时取消登录处理,通过调用pqcws->->QueryContinue() 是否返回S_OK接收用户是否进行了取消登录处理,具体代码实现样例如下:
HRESULT TestCredential::Connect(_In_ IQueryContinueWithStatus* pqcws)
{OutputDebugStringA(__FUNCTION__);IQueryContinueWithStatus* pStatus = pqcws;Sleep(1000);pStatus->SetStatusMessage(L"请按压指纹进行指纹登录比对验证...");for (int i = 0; i < 10 && pStatus->QueryContinue() == S_OK; i++) {Sleep(1000); // 模拟耗时操作std::wstring progressMsg = L"比对进度: " + std::to_wstring((i + 1) * 10) + L"%";pStatus->SetStatusMessage(progressMsg.c_str());}pStatus->SetStatusMessage(L"指纹比对成功!");Sleep(1000);return S_OK;
}如下展示了Connect方法执行时用户取消登录时所展示界面,此时显示的为“已取消登录!”,正常登录时其显示的为开发者定义的交互提示语如上面代码中的“指纹比对成功!”,此处不好截图,就不做样例图展示了。

