Windows 凭据提供程序、筛选器和解锁工作站场景
我正在开发一个凭证提供程序和过滤器。我在锁定场景方面遇到一些问题。
首先,我尝试了此处的 SampleAllControlCredentialProvider 。它有效。即使我随后登录并锁定它,它也会显示我的凭据。
其次,我尝试通过添加一些代码行来制作自己的凭据提供程序过滤器。过滤器正在过滤掉 Windows 的凭据,只允许显示我的凭据。这些是我添加的代码:
在 CSampleProvider.h 中,我使该类得以实现 ICredentialProviderFilter
class CSampleProvider : public ICredentialProvider, public ICredentialProviderFilter
在 CSampleProvider.h 中,我将 STDMETHOD (QueryInterface) 更改为
STDMETHOD (QueryInterface)(REFIID riid, void** ppv)
{
HRESULT hr;
if (IID_IUnknown == riid)
{
*ppv = this;
AddRef();
hr = S_OK;
}
else if (IID_ICredentialProvider == riid)
{
*ppv = static_cast<ICredentialProvider*>(this);
AddRef();
hr = S_OK;
}
else if (IID_ICredentialProviderFilter == riid)
{
*ppv = static_cast<ICredentialProviderFilter*>(this);
AddRef();
hr = S_OK;
}
else
{
*ppv = NULL;
hr = E_NOINTERFACE;
}
return hr;
}
在 CSampleProvider.h 中,我添加这些代码行
//ICredentialProviderFilter
public:
/**
* \brief method to filter CPProvider
* \param cpus - CP usage scenario
* \param dwFlags
* \param rgclsidProviders
* \param rgbAllow
* \param cProviders
* \return IFACEMETHODIMP
*/
IFACEMETHODIMP Filter(
CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
DWORD dwFlags,
GUID *rgclsidProviders,
BOOL *rgbAllow,
DWORD cProviders);
/**
* \brief method to update remote logon credential
* \param pcpcsIn - serialized logon credential
* \param pcpcsOut - returned logon credential
* \return IFACEMETHODIMP
*/
IFACEMETHODIMP UpdateRemoteCredential(
const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcsIn,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcsOut);
然后,这是过滤器方法的实现(在 CSampleProvider.cpp 内):
HRESULT CSampleProvider::Filter(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,DWORD dwFlags,GUID* rgclsidProviders,BOOL* rgbAllow,DWORD cProviders)
{
//UNUSED(dwFlags);
UNREFERENCED_PARAMETER(dwFlags);
MessageBox(NULL, "Filter!", "Trace", NULL);
switch (cpus)
{
case CPUS_LOGON:
case CPUS_UNLOCK_WORKSTATION:
//Filters out the default Windows provider (only for Logon and Unlock scenarios)
for (int i = 0; i < (int)cProviders; i++)
{
if (IsEqualGUID(rgclsidProviders[i], CLSID_CSampleProvider)) rgbAllow[i]=true;
else rgbAllow[i] = false;;
//rgbAllow[i]=true;
}
return S_OK;
case CPUS_CREDUI:
case CPUS_CHANGE_PASSWORD:
return E_NOTIMPL;
default:
return E_INVALIDARG;
}
}
HRESULT CSampleProvider::UpdateRemoteCredential(const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsIn, CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsOut)
{
UNREFERENCED_PARAMETER(pcpcsOut);
UNREFERENCED_PARAMETER(pcpcsIn);
return E_NOTIMPL;
}
最后,我运行此 . reg 文件包含:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}]
@="SampleAllControlsCredentialProvider"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}]
@="SampleAllControlsCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}]
@="SampleAllControlsCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}\InprocServer32]
@="SampleAllControlsCredentialProvider.dll"
"ThreadingModel"="Apartment"
实际上,除了锁定场景之外,一切都运行良好。因此,成功登录后,我单击“锁定”。通常,如果我切换用户或注销,我的凭据应该出现在登录屏幕上。但现在,仅实施过滤器后,什么也没有出现,只有蓝色的登录屏幕,没有任何凭据。
有谁知道会发生什么以及该怎么做?
I'm developing a credential provider and filter. I have some problems with lock scenario.
First, I have tried the SampleAllControlCredentialProvider from here. And it works. Even when I logon and lock it afterward, it shows my credential.
Second, I tried making my own credential provider filter by adding some lines of codes. The filter is filtering out the windows' credential, only my credentials are allowed to appear. These are my addition of codes:
In CSampleProvider.h, I make the class to be implementing
ICredentialProviderFilter
class CSampleProvider : public ICredentialProvider, public ICredentialProviderFilter
In CSampleProvider.h, I change the STDMETHOD (QueryInterface) into
STDMETHOD (QueryInterface)(REFIID riid, void** ppv)
{
HRESULT hr;
if (IID_IUnknown == riid)
{
*ppv = this;
AddRef();
hr = S_OK;
}
else if (IID_ICredentialProvider == riid)
{
*ppv = static_cast<ICredentialProvider*>(this);
AddRef();
hr = S_OK;
}
else if (IID_ICredentialProviderFilter == riid)
{
*ppv = static_cast<ICredentialProviderFilter*>(this);
AddRef();
hr = S_OK;
}
else
{
*ppv = NULL;
hr = E_NOINTERFACE;
}
return hr;
}
Still in CSampleProvider.h, I add these lines of codes
//ICredentialProviderFilter
public:
/**
* \brief method to filter CPProvider
* \param cpus - CP usage scenario
* \param dwFlags
* \param rgclsidProviders
* \param rgbAllow
* \param cProviders
* \return IFACEMETHODIMP
*/
IFACEMETHODIMP Filter(
CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
DWORD dwFlags,
GUID *rgclsidProviders,
BOOL *rgbAllow,
DWORD cProviders);
/**
* \brief method to update remote logon credential
* \param pcpcsIn - serialized logon credential
* \param pcpcsOut - returned logon credential
* \return IFACEMETHODIMP
*/
IFACEMETHODIMP UpdateRemoteCredential(
const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcsIn,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcsOut);
Then, this is the implementation of the filter methods (inside the CSampleProvider.cpp):
HRESULT CSampleProvider::Filter(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,DWORD dwFlags,GUID* rgclsidProviders,BOOL* rgbAllow,DWORD cProviders)
{
//UNUSED(dwFlags);
UNREFERENCED_PARAMETER(dwFlags);
MessageBox(NULL, "Filter!", "Trace", NULL);
switch (cpus)
{
case CPUS_LOGON:
case CPUS_UNLOCK_WORKSTATION:
//Filters out the default Windows provider (only for Logon and Unlock scenarios)
for (int i = 0; i < (int)cProviders; i++)
{
if (IsEqualGUID(rgclsidProviders[i], CLSID_CSampleProvider)) rgbAllow[i]=true;
else rgbAllow[i] = false;;
//rgbAllow[i]=true;
}
return S_OK;
case CPUS_CREDUI:
case CPUS_CHANGE_PASSWORD:
return E_NOTIMPL;
default:
return E_INVALIDARG;
}
}
HRESULT CSampleProvider::UpdateRemoteCredential(const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsIn, CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsOut)
{
UNREFERENCED_PARAMETER(pcpcsOut);
UNREFERENCED_PARAMETER(pcpcsIn);
return E_NOTIMPL;
}
Finally, I run this .reg file containing:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}]
@="SampleAllControlsCredentialProvider"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}]
@="SampleAllControlsCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}]
@="SampleAllControlsCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{F2ADF4EC-5DAA-407e-9776-10B25A64A435}\InprocServer32]
@="SampleAllControlsCredentialProvider.dll"
"ThreadingModel"="Apartment"
Actually, everything works well except just for the lock scenario. So, after I successfully logon, I click lock. Usually, if I switch user or log off, my credentials should appear there on the logon screen. But now, after only implementing the filter, There appears nothing, only the blue logon screen without any credential.
Does anyone know what happens and what to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我知道这个问题很旧,但由于它是在几个月前编辑的,因此它可能仍然相关。
我相信在您的解锁场景下,您将自己的凭证提供者排除在运行之外;尝试将“CLSID_CSampleProvider”更改为“CLSID_PasswordCredentialProvider”,看看有什么效果。我有一个正在运行的 Wrap Credential Provider,并且我正在使用具有此 ID 的过滤器,并且它工作得很好。我的凭据显示在登录和解锁场景下。
I know this question is old, but as it was edited only a couple of months ago it might still be relevant.
I believe under your unlock scenario, you are excluding your own credential provider from running; try changing: 'CLSID_CSampleProvider' to 'CLSID_PasswordCredentialProvider' and see what effect thats has. I have a Wrap Credential Provider running and I am using the filter with this ID and its working perfectly. My credentials appear under the logon and unlock scenarios.