您提供的链接完全正确。您需要在.NET中实现一个COM对象,该对象实现以下两个COM接口(至少):ICredentialProvider,ICredentialProviderCredential
首先,您必须在.NET中公开它们,以便引用它们。根据我的经验,更简单的方法是通过Windows SDK中的IDL。您需要的idl文件将是\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\um\credentialprovider.idl
。
抓#1:你需要用所有的定义在那里的library CredentialProviders { ... }
声明,否则只能类型的一些将获得出口)
打开VS本地工具和编译与midl
: midl "C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\um\credentialprovider.idl"
这将创建一个类型库(tlb文件),然后.NET可以使用它来将类型转换为C#类型。您现在可以使用tlbimp
实用程序来创建那么您可以在.NET中使用互操作的dll: tlbimp.exe credentialprovider.tlb /out:CredentialProvider.Interop.dll
捕捉#2:与tlbimp
编译不幸条的返回类型的方法调用(HRESULT
)和期望您使用.NET异常子系统。由于winlogon(或credUI主机应用程序)重新抛出异常并终止进程,因此在这种情况下不起作用。解决方案是使用名为tlbimp2
的实用程序。在写这篇文章的时候,它是在codeplex上托管的,只有代码可用。我不得不下载代码并在VS2017中重新编译工具(我已经将附件上传到了附件中)。因此,我们需要以运行此编译为winlogon的: tlbImp2.exe credentialprovider.tlb /out:CredentialProvider.Interop.dll /unsafe /verbose /preservesig
现在我们可以开始,我们可以实现了COM对象库。在.NET框架中启动一个dll项目。编辑项目并确保选中“注册COM互操作”标志。参考已编译的Interop库。
如前所述,我们需要实现两个接口:ICredentialProvider,ICredentialProviderCredential。代码应如下所示:
[ComVisible(true)]
[Guid("<random-guid>")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITestWindowsCredentialProvider: ICredentialProvider
{
}
您可以对ICredentialProviderCredential接口完全相同。
在执行:从所有方法E_NOTIMPL
[ComVisible(true)]
[Guid("<another-unique-id>")] // <-- This is what we are going to use for registration
[ClassInterface(ClassInterfaceType.None)]
public class TestWindowsCredentialProvider : ITestWindowsCredentialProvider
{
private const int E_NOTIMPL = unchecked((int) 0x80004001);
...
public int SetSerialization(ref _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcs)
{
return E_NOTIMPL;
}
...
}
收益与所有out
参数提供值。现在我们有一个可以开始的基础对象。您可以延迟ICredentialProviderCredential的实现,直到您实现ICredentialProvider :: GetCredentialAt方法。
您可以通过在注册表设置HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers
下添加一个用组件的实现guid命名的密钥来注册此凭据提供程序(请在此记住括号)。
当你这样做的登录服务和credUI调用将加载和查询您的组件。不过要注意的是:任何异常都会使winlogon崩溃,导致无法登录。使用虚拟机作为最佳实践。
现在,在完成所有这些步骤之后,我们仍然需要实施凭证提供程序。这最好在名为Credential Provider driven Windows Logon Experience的文档中描述。您最终需要用任何可能的事情编排UI,以便在后台执行此操作并将其映射到用户。
在正确序列化方法实现ICredentialProviderCredential :: GetSerialization的用户信息时,您将能够登录用户。
例
我已经做了这样的一个例子,你可以在这里找到:https://github.com/phaetto/windows-credentials-provider
http://pgina.org/和编写插件是最简单的方法,这就是假定允许的。 –
不幸的是它不是@Alex K. 这是我的第一个方法,但我没有被允许。 – loveMeansNothing
您是否能找到有用的@loveMeansNothing?我也在同一条船上 –