Credential Provider Filter
来源:互联网 发布:四川大学网络教育吧 编辑:程序博客网 时间:2024/05/19 13:58
I've implemented a Credential Provider based on the MS samples, and I would
like it to filter out the default MS password provider. To keep things
simple, I decided to implement the ICredentialProviderFilter interface on my
main Credential Provider class (which works fine). To do that, I updated the
class to implement ICredentialProviderFilter, implemented the Filter and
UpdateRemoteCredential methods, and registered the assembly in the registry
as a Credential Provider filter.
Unfortunately, something isn't working. As far as I can tell the Filter
method is never getting called, and I'm wondering what I've missed. I've
included the relevant sections of code (and registry entries):
--CLMSProvider.h--
class CLMSProvider : public ICredentialProvider, public
ICredentialProviderFilter
{
//***SNIP***
public:
//***SNIP: ICredentialProvider methods ***
IFACEMETHODIMP Filter(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus, DWORD
dwFlags, GUID* rgclsidProviders, BOOL* rgbAllow, DWORD cProviders);
IFACEMETHODIMP UpdateRemoteCredential(const
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsIn,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsOut);
//***SNIP***
--CLMSProvider.cpp--
//***SNIP***
//Function to filter out other credential providers
HRESULT CLMSProvider::Filter(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus, DWORD
dwFlags, GUID* rgclsidProviders, BOOL* rgbAllow, DWORD cProviders)
{
//DEBUG
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)
//TODO: This isn't working
for (int i = 0; i < cProviders; i++)
{
if (IsEqualGUID(rgclsidProviders[i], CLSID_PasswordCredentialProvider))
rgbAllow[i] = FALSE;
}
return S_OK;
case CPUS_CREDUI:
case CPUS_CHANGE_PASSWORD:
return E_NOTIMPL;
default:
return E_INVALIDARG;
}
HRESULT CLMSProvider::UpdateRemoteCredential(const
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsIn,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsOut)
{
return E_NOTIMPL;
-------------------
--Register.reg--
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{3E340420-5103-11DC-99F1-DB9156D89593}]
@="LMSCredentialProvider"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{3E340420-5103-11DC-99F1-DB9156D89593}]
@="LMSCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{3E340420-5103-11DC-99F1-DB9156D89593}]
@="LMSCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{3E340420-5103-11DC-99F1-DB9156D89593}\InprocServer32]
@="LMSCredentialProvider.dll"
"ThreadingModel"="Apartment"
-------------------
So, what did I miss? Any help would be appreciated. Thanks!
You shouldn't need to manually instantiate the filter. You just register it,
and code enough of the COM boilerplate that when Windows asks your DLL for an
instance, it can be generated. From your post, I'm not sure if you're doing
that or not, so I'll go ahead and post some code samples for you and anyone
else who comes looking.
Here's a snippet from my "register.reg":
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{<LMSCredentialProvider GUID Snipped>}]
@="LMSCredentialProvider"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{<LMSCredentialProvider GUID Snipped>}]
@="LMSCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{<LMSCredentialProvider GUID Snipped>}]
@="LMSCredentialProvider"
[HKEY_CLASSES_ROOT\CLSID\{<LMSCredentialProvider GUID
Snipped>}\InprocServer32]
@="LMSCredentialProvider.dll"
"ThreadingModel"="Apartment"
As mentioned in the other thread, I have a separate class for the filter in
the same DLL.
Here is CLMSFilter.h:
#pragma once
#include "credentialprovider.h"
#include <windows.h>
#include <strsafe.h>
#include "dll.h"
//This class implements ICredentialProviderFilter, which is responsible for
filtering out other credential providers.
//The LMS Credential Provider uses this to mask out the default Windows
provider.
class CLMSFilter : public ICredentialProviderFilter
{
public:
//This section contains some COM boilerplate code
// IUnknown
STDMETHOD_(ULONG, AddRef)()
{
return _cRef++;
}
STDMETHOD_(ULONG, Release)()
{
LONG cRef = _cRef--;
if (!cRef)
{
delete this;
}
return cRef;
}
STDMETHOD (QueryInterface)(REFIID riid, void** ppv)
{
HRESULT hr;
if (IID_IUnknown == riid ||
IID_ICredentialProviderFilter == riid)
{
*ppv = this;
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
hr = S_OK;
}
else
{
*ppv = NULL;
hr = E_NOINTERFACE;
}
return hr;
}
public:
friend HRESULT CLMSFilter_CreateInstance(REFIID riid, __deref_out void**
ppv);
//Implementation of ICredentialProviderFilter
IFACEMETHODIMP Filter(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus, DWORD
dwFlags, GUID* rgclsidProviders, BOOL* rgbAllow, DWORD cProviders);
IFACEMETHODIMP UpdateRemoteCredential(const
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsIn,
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcsOut);
protected:
CLMSFilter();
__override ~CLMSFilter();
private:
LONG _cRef;
You shouldn't need to do anything special with your CredentialProvider class.
You will also need to modify dll.cpp to know about your Credential Provider
filter class. I believe the only changes I made to the basic MS sample were:
1. add "extern HRESULT CLMSFilter_CreateInstance(REFIID riid, void** ppv);"
towards the top of the file.
2. Modify the function with signature "STDMETHOD (CreateInstance)(IUnknown*
pUnkOuter, REFIID riid, void** ppv)" to be as follows:
STDMETHOD (CreateInstance)(IUnknown* pUnkOuter, REFIID riid, void** ppv)
{
HRESULT hr;
if (!pUnkOuter)
{
if (IID_ICredentialProvider == riid)
hr = CLMSProvider_CreateInstance(riid, ppv);
else if (IID_ICredentialProviderFilter == riid)
hr = CLMSFilter_CreateInstance(riid, ppv);
}
else
{
hr = CLASS_E_NOAGGREGATION;
}
return hr;
}
I think that's everything. Go ahead and check your code against what I've
posted: hopefully, there's something there that will help you out.
http://groups.google.com/group/microsoft.public.platformsdk.security/browse_thread/thread/991af38944518e64/e8f5eb044961cbf1
- Credential Provider Filter
- Credential Provider
- Credential Provider
- Credential Provider
- GINA & Credential Provider
- Credential Provider Technical Reference
- Credential provider 架构
- win7 登陆机制Credential Provider
- credential Provider 简易改写攻略
- 调试 Credential Provider 的简单方法
- Login from Credential Provider without Submit button
- 调试 Credential Provider 的简单方法
- 用Vmware+Vista SDK进行Vista Credential Provider开发 (一)
- 用Vmware+Vista SDK进行Vista Credential Provider开发
- Credential Providers
- PowerShell Credential
- provider
- <provider>
- DB2 load
- Compare the function: SQL server vs ORACLE
- 将request对象map中的值封装成数据实体对象
- 设置浏览器禁止访问某网站
- myEclipse 快捷键设置详解
- Credential Provider Filter
- android 通知 手机 媒体 数据库 更新
- C++经验之检测内存泄露
- Windows x86 内存管理及分页机制
- CentOS安装后的国内更新源和DAG
- 内核模式DLL
- Shell标准输出、标准错误 >/dev/null 2>&1
- oracle 中文字段查询后结果集标题显示为"???"
- fedora15 配置rails3 和mysql