目录

使用条款。2

发行说明。三

样本凭证提供者3

SampleCredentialProvider代码库。4

项目结构。4

扩展SampleCredentialProvider 5的常见任务

提示和技巧。7

自动化部署过程。7

与CredUI 7一起开发

调试LogonUI 8

如果你的系统变得不稳定。9

样本creduicredentialprovider 10

SampleAllControlsCredentialProvider 10

SampleHardwareEventCredentialProvider 11

SamplewrappexistingCredentialProvider 13

默认平铺。15

正在包装现有凭据提供程序。15

凭据提供程序体系结构。17

总结。17

问题。17

附录A-常见问题。18

使用条款

本规范和信息按“原样”提供,无任何明示或暗示的保证,包括但不限于对适销性和/或特定用途适用性的暗示保证。

本文档中的信息,包括URL和其他Internet网站引用,如有更改,恕不另行通知。——除非另有说明,否则此处描述的示例公司、组织、产品、域名、电子邮件地址、徽标、人员、地点和事件均为虚构,且与任何真实的公司、组织均无关联,产品、域名、电子邮件地址、徽标、人员、地点或事件是有意或应该推断的。——遵守所有适用的版权法是用户的责任。——在不限制版权下的权利的情况下,本文档的任何部分都不得复制、存储或引入检索系统,也不得在任何未经微软公司明确书面许可,以任何方式(电子、机械、影印、录音或其他方式)或任何目的提供的表格。

微软可能拥有专利、专利申请、商标、版权或其他涉及本文档主题的知识产权。——除非微软的任何书面许可协议中明确规定,否则本文档的提供不会授予您对这些专利、商标、版权的任何许可,或其他知识产权。

 

版权所有(c)2006 Microsoft Corporation。保留所有权利。

Microsoft、Windows Vista、Windows XP和Visual Studio是Microsoft Corporation在美国和/或其他国家/地区的注册商标或商标。介绍

在本文档中,我们将查看一些自定义Windows Vista凭据提供程序示例。具体而言,我们将涵盖以下主题:

1.    了解基本SampleCredentialProvider代码库。

2.    扩展基本SampleCredentialProvider代码库的常见任务。

3.    支持CredUI的SampleCredUICredentialProvider。

4.    SampleAllControlsCredentialProvider,它公开每个可能的UI控件。

5.    SampleHardwareEventCredentialProvider,它支持异步事件。

6.    SampleWrapeExistingCredentialProvider,它在Windows Vista中包装默认的用户名/密码凭据提供程序。

发行说明

这是样本的第三个版本。第一个版本是针对2月份的CTP。第二个版本是针对Beta2并添加了额外的样本。第三个版本更新了RTM的样本。

更改包括

)修复解锁。Beta2之后,Windows Vista更改为需要KerbWorkstationUnlockLogon消息类型来解锁计算机,并需要KerbInteractiveLogon消息类型来登录计算机。以前,它将接受KerbInteractiveLogon消息类型来登录和解锁。示例已相应更新。[3.0版]

使用CredProtect在凭据序列化时加密密码。[3.0版]

更新项目设置以支持VisualC++快件。[3.0版]

更新SampleCredUICredentialProvider以处理额外的Credui场景,例如正确处理CREDUIWIN PACK_32_WOW[v3.0]

修复了SamplewrappExistingCredentialProvider中的一些问题。对ICredentialProviderCredentialEvents的任何回调都将失败,因为它混淆了哪个是credprov哪个是后者。以及其他症状,这导致更改过期密码失败。解决方案是让包装器credprov提供一个ICredentialProviderCredentialEvents。[3.0版]

概要现在包括FAQ(附录A)[v3.0]

样品认证提供者

开箱即用,SampleCredentialProvider提供了一个DLL项目,该项目公开了开发凭据提供程序所需的两个COM接口:ICredentialProvider和ICredentialProviderCredential。ICredentialProvider公开枚举可用凭据的功能,ICredentialProvider credential公开身份验证过程中每个特定凭据所需的功能。

SampleCredentialProvider代码库

SampleCredentialProvider项目提供一个工作的基线凭据提供程序。此示例是硬编码以公开两个帐户:Administrator和Guest。下面的屏幕截图显示了在加入域的计算机上这可能是什么样子。


项目结构

SampleCredentialProvider项目包括一组小文件,每个文件都有自己的用途:

文件

目的

普通.h

描述凭据的UI和布局。编辑此文件以更改每个凭据磁贴中UI元素的数目和类型。

CSampleCredential.h/.cpp文件

定义凭据磁贴的行为。编辑这些文件以更改磁贴响应用户输入的方式。

CSampleProvider.h/.cpp

定义凭据提供程序的行为,该提供程序通常管理一个或多个CSampleCredentials。编辑此文件以更改枚举凭据的方式。

dll.h/.cpp,samplecredentialprovider.def

满足COM服务器和DLL要求的基线支持。你应该编辑这些文件。

guid.h/.cpp文件

定义提供程序抯GUID。你需要编辑guid.h以引用你的唯一guid。

helpers.h/.cpp帮助程序

提供使用UNICODE字符串和身份验证包的实用程序方法。你应该编辑这些文件。

Register.reg,Unregister.reg注册

分别注册和注销示例凭据提供程序。您需要编辑这些文件,以便在任何出现GUID的地方使用GUID.h中的GUID。您还需要编辑Register.reg文件以反映对象的名称(前两个注册表项)和DLL的名称(第三个注册表项)。

资源.h,资源.rc

管理提供程序资源,如磁贴图像。如果要向凭据提供程序添加更多资源(如图像),请编辑这些文件。

tileimage.bmp公司

要在凭证磁贴上显示的图像。编辑此文件(或添加其他图像)以更改磁贴中显示的图像。


扩展SampleCredentialProvider的常见任务

由于SampleCredentialProvider为开发自定义提供程序提供了一个很好的基线,因此建议您自定义它以满足您的需要,而不是从头开始。以下步骤将引导您完成自定义所有扩展通用的SampleCredentialProvider项目的过程。

我们使用“yCredentialProvider”作为新的项目名称,所以一定要更改它以反映您想要使用的名称。我们也不会重命名任何文件夹或文件以反映名称,除非需要成功构建,所以这可能是您在熟悉代码库后选择要做的事情。

请注意,这些示例是针对Windows Vista的RTM版本运行的。它们应该针对Windows Vista SDK的RTM版本进行编译。

1.    在工具选项中设置Visual Studio 2005,以使用SDK中的可执行文件、includes和libs,而不是随VS.一起提供的可执行文件、includes和libs。有关如何执行此操作的详细信息,请参阅SDK目录根目录中的ReleaseNotes.Htm。

2.    在SampleCredentialProvider文件夹中,双击SampleCredentialProvider.sln以在Visual Studio 2005中打开它。

3.    在解决方案资源管理器中,右键单击SampleCredentialProvider项目节点并选择“重命名”。将名称更改为“yCredentialProvider”,然后按回车键锁定。

4.    在解决方案资源管理器中,右键单击MyCredentialProvider项目节点并选择“属性”。这将启动MyCredentialProvider属性页对话框。

5.    在左边的树视图中,选择配置属性c/C++节点。

6.    确保Vista SDK包含目录的路径包含在其他包含目录中。在默认安装中,它最终会出现在“ProgramFiles\Microsoft SDKs\Windows\v1.0\Include”。

7.    在左树状图中,选择配置属性链接器节点以显示链接器配置的常规属性。

8.    确保Vista SDK库目录的路径包含在其他库目录中。在默认安装中,它最终位于“Program Files\Microsoft SDKs\Windows\v1.0\Lib”。

9.    按“确定”关闭对话框。

10. 打开samplecredentialprovider.def。将“AMPLECREDENTIALPROVIDER.DLL”更改为“YCREDENTIALPROVIDER.DLL”。保存samplecredentialprovider.def。

11. 打开guid.h。用唯一的guid替换DEFINE\u guid中的guid。可以从“创建GUID”工具生成唯一的GUID。以后一定要记住。保存guid.h。

12. 在记事本或Visual Studio中打开Register.reg(不要在资源管理器中执行)。用上一步创建的guid替换每个注册表项中的guid。同时将“ampleprovider”更改为“yCredentialProvider”,并将“SampleCredentialProvider.dll”更改为“MyCredentialProvider.dll”。保存Register.reg。

13. 在记事本或Visual Studio中打开Unregister.reg(不要在资源管理器中执行)。将注册表项中的GUID替换为Register.reg中使用的GUID。保存Unregister.reg。

14. 选择构建|构建解决方案。如果存在任何生成错误,请查看上面的步骤。

15. 将新生成的MyCredentialProvider.dll复制到测试计算机的System32目录。

16. 将Register.reg复制到测试计算机,并从资源管理器运行它以注册凭据提供程序。

17. 从“开始”菜单中,选择切换用户的选项。

18. 登录屏幕现在应该有一个额外的管理员和来宾帐户。——如果您看到的只是一个大的互动程序,请单击“切换用户”查看互动程序列表。

19. 您应该能够使用新创建的管理员帐户磁贴登录。由于系统的安全设置,来宾帐户可能已启用,也可能未启用。

20. 如果要删除示例,请将Unregister.reg复制到测试计算机并运行它以注销凭据提供程序。


提示和技巧

以下是一些在开发周期中可以帮助您的提示和技巧。在查看本文档后面介绍的其他示例时,请记住这些内容非常有用。


自动化部署过程

如果首先在测试计算机上进行开发,则可以通过添加自动将输出DLL复制到System32目录的生成后事件来自动执行的DLL部署过程。例如,可以转到“项目属性页”对话框的“配置属性”“生成事件”“生成后事件”选项卡,并为命令行设置以下内容:

复制“$OutDir\$ProjectName.dll”%systemroot%\system32/Y

但是,在执行第二次构建时要小心,因为生成后事件只在成功构建之后发生,并且VisualC++将跳过编译过程,如果二进制文件已经是最新的。

与CredUI一起开发

尽管您可能不希望在最终的凭据提供程序中支持CredUI场景,但如果您是在测试计算机上开发的,则可能希望在开发和调试期间使用它。由于CredUI场景是从正常的桌面会话运行的,因此您可以在运行时将Visual Studio调试器附加到它,从而大大简化了开发和测试过程。

为此:

1.    在Visual Studio中创建一个新的Win32控制台项目。

2.    更新新项目的主功能以调用CredUIPromptForWindowsCredentials,例如:

#包括“stdafx.h”

#包括<windows.h>

#包括<WinCred.h>

int tmain(int argc,_TCHAR*argv[])

{

–BOOL save=false;

'-DWORD authPackage=0;

—LPVOID authBuffer;

–ULONG authBufferSize=0;

—信用信息;

credUiInfo.pszCaptionText=文本(“我的标题”);

credUiInfo.pszMessageText=文本(“我的消息”);

credUiInfo.cbSize=sizeof(credUiInfo);

credUiInfo.hbmBanner=空;

credUiInfo.hwndParent=空;

creduipromptforwindows凭据(&(credUiInfo),0,&(authPackage),

牋NULL,0,&authBuffer,&authBufferSize,&(save),0);

}

3.    更新项目以链接CredUI.lib。您可能需要更新“附加包含目录”和“附加库目录”,以便从“项目属性页”对话框指向Windows Vista SDK。

4.    将凭据提供程序项目添加到解决方案中。

5.    生成凭据提供程序,并确保将最新版本部署到System32目录并注册为凭据提供程序。

6.    设置断点等,然后在调试模式下运行控制台应用程序。从控制台应用程序调用CredUIPromptForWindowsCredentials后,应根据需要命中断点。

调试LogonUI

简而言之:在测试机和调试机之间连接kd,然后将ntsd通过kd传输给logonUI。关于如何在web上实现这一点,有相当多的信息(虽然不是专门针对logonUI的)。但是这里有一些基本的指针。

  1. 安装调试程序包(http://www.microsoft.com/whdc/devtools/debugging/default.mspx)
  2. 在两台计算机之间设置kd(有关详细信息,请访问web或MSDN)
    1. 连接调试电缆
    2. 在被调试器计算机上,运行如下所示的操作(根据需要更改命令行参数)

i、 Bcdedit杁ebug打开

二。Bcdedit杁bgsettings串行调试端口:1波特率:115200

  1. 重新启动调试对象
  2. 在调试器计算机上,运行类似于

i、 Kd.exe杛杗com:port=com1,baud=115200

  1. 将您需要的本地符号复制到方框中,因为NTSD won抰可以访问网络
  2. 在HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options下创建名为logonui.exe的密钥
  3. 在logonui.exe键中,创建一个名为Debugger的字符串值
    1. 用计算机上ntsd.exe的路径填充该值,例如C:\调试器\ntsd.exe-d-gG-y<path to local symbols>(需要在杫和path之间留出空间)
    2. 杁将NTSD输出管道到KD
    3.   忽略进程中的初始启动断点(如果您希望在第一次执行设置BPs时进程立即中断,请不要设置小g)
    4. 朑忽略终止断点,因此进程将悄悄退出
    5. 杫为NTSD设置被调试器上的本地符号路径
  4. 加载.DLL时中断(不是必需的,但很好地知道是否需要)
    1. 对于加载.dll的可执行文件,请遵循以上所有步骤,但不要设置小g标志,然后当进程启动时,NTSD将打断
    2. 键入sxeld<dll name>
    3. 然后,调试器和NTSD将在加载该dll时中断,您可以设置断点等。

如果你的系统变得不稳定

在凭据提供程序的开发过程中,很可能会弄乱凭据提供程序,甚至可能导致LogonUI崩溃。

不要惊慌。

通常,您可以在安全模式下重新启动Windows(在早期启动过程中反复点击F8进行此操作)。在安全模式下,您应该能够使用普通密码提供程序登录,此时您可以注销有问题的凭据提供程序。

另一件事是,通过从注册表中删除一个或多个内置凭据提供程序的项,可能会意外地注销该提供程序。以下是来自HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers的密钥,供参考:

供应商

钥匙

通用提供程序

{25CBB996-92ED-457e-B28C-4774084BD562}

密码提供程序

{6f45dc1e-5384-457a-bc13-2cd81b0d28ed}

智能卡凭据提供程序

{8bf9a910-a8ff-457f-999f-a5ca10b4a885}

在安全模式下重新启动后,您应该能够重新输入它们。

样品提供器

WindowsVista引入了CredUIPromptForWindowsCredentials,它可以被认为是下一代CredUIPromptForCredentials(尽管CredUIPromptForCredentials仍然保持向后兼容)。与CredUIPromptForCredentials不同,CredUIPromptForWindowsCredentials依赖于登录屏幕使用的相同凭据提供程序。虽然实现这些凭证提供程序基本上是相同的,但有一个地方您需要对凭证提供程序的工作方式做出决定。

CSampleProvider::SetUsageScenario的实现包含了我们添加对CredUI支持所需的一切。使用特定的使用方案(凭据提供程序使用方案)调用此方法,该方案询问凭据提供程序是否支持它。默认情况下,SampleCredentialProvider不支持CPU凭据使用方案,这意味着使用CredUIPromptForWindowsCredentials的应用程序将无法访问通过它提供的凭据。但是,我们已经为SampleCredUICredentialProvider更改了这一点,因为我们对CPU-CREDUI场景的请求的处理方式与CPU-LOGON相同,因此它将在CREDUI场景中枚举相同的两个磁贴。

SampleAllControlsCredentialProvider

SampleAllControlsCredentialProvider项目演示了九个可供凭据提供程序使用的UI控件中的每一个。这里是从LogonUI运行此示例时看到的示例:

转存失败重新上传取消

请注意,注销按钮由LogonUI自动插入。

此示例的优点之一是它与前面讨论的基本示例凭据提供程序略有不同。具体来说,改变的关键区域是共同的。

在Common.h中,我们为SAMPLE_FIELD_ID枚举添加了更多控件,并为s_rgFieldStatePairs和s_rgcredprovfielddescriptor分别添加了条目。正如您从上面的屏幕截图中看到的,只有“文件图像”和“大文本”配置为在“选定”和“取消选定”模式下同时显示,而“小文本”配置为仅在取消选定平铺时显示。所有其他控件仅显示在选定的磁贴中。要更改此行为,请修改s抯rgFieldStatePairs的第二个成员(它是凭证提供程序交互状态)。

除了Common.h中的新字段之外,还需要在CSampleCredential.cpp实现中添加对每种类型控件的支持。默认情况下,基示例仅实现对字符串和位图方法(如GetStringValue等)的支持。由于这些是示例中使用的唯一控件类型,因此可以从未使用的控件方法(如GetCheckboxValue)返回E_NOTIMPL。然而,由于我们现在使用这些控件,我们实现了对获取和设置它们各自的值的支持。

控制

所需方法

蒂莱马吉

获取位图值

大文本,小文本

获取字符串值

编辑文本,

SFI_密码

获取字符串值,

设置字符串值

“提交”按钮

GetSubmitButtonValue

SFI_复选框

获取复选框值,

SetCheckBox值

SFI_组合框

GetComboBox值计数,

获取ComboboxValueat,

设置组合框SelectedValue

SFI_命令链接

获取字符串值,

已单击CommandLink

SampleHardwareEventCredentialProvider

自定义凭据的常见场景涉及外部事件,例如指纹扫描仪生成的消息到达。SampleHardwareEventCredential示例演示了如何处理此类异步事件。

运行时,此示例显示一个带有单个按钮的窗口。此窗口用于模拟具有两种状态的外部元素:已连接和已断开连接。断开连接时,凭据仅显示一个大文本,要求用户连接:

通过按下“按ress连接”按钮,您可以模拟硬件事件,如刷指纹,凭证提供不同的控件,允许用户登录:

由于在处理硬件事件时无法更改特定凭据使用的控件(因为您尚未收到有关ICredentialProviderCredentialEvents的建议),此示例实际上实现了两个凭据:租用连接消息凭据和实际登录凭据,这实际上与来自SampleCredentialProvider项目的CSampleCredential相同。根据连接模拟器窗口的状态,提供程序将显示正确的连接模拟器窗口。

窗口是在一个单独的线程上创建的,该线程为它提供了一种在提供程序线程由外部授权管理时泵送消息的方法。当按下按钮时,窗口线程将调用提供程序,要求它通过调用先前通知调用中收到的ICredentialProviderEvents指针上的CredentialsChanged方法来重新枚举其凭据:

枚举凭据时,将再次调用GetCredentialCount和GetFieldDescriptorCount等方法。反过来,提供程序检查连接仿真器的状态,并为相应的凭据提供数据。在这两种情况下,始终只显示一个凭证。请注意,我们将调用从单独线程更改的凭据,这是可以做到的。但是,在尝试从独立线程调用其他方法时要格外小心。

虽然此示例演示了如何将窗口上的按钮用作事件,但您可以自定义ccommandwind::ThreadProc以查找所需的任何事件,前提是安全桌面上支持它。

样本包装现有凭证提供程序

在某些情况下,您可能会发现现有的凭据提供程序满足您的几乎所有需要,但需要从用户检索的额外字段或两个字段除外。不得不重新实现现有凭据提供程序的功能是很遗憾的,因此此示例演示了包装现有凭据提供程序并用两个附加字段扩展它的过程。

请注意,封装(或“包装”)应谨慎使用。它不是GINA链接行为的万能替代品。与GINA链接不同,您添加的行为仅适用于用户单击您的凭证磁贴时,而不适用于用户单击其他凭证磁贴时

只有在明确知道包装的credprov的行为时,才应该显式地执行此操作。如果要扩展包装的credprov正在获取的凭据信息,则应该使用此操作。如果只想对另一个credprov收集的凭据执行额外操作,那么网络提供者可能比凭证提供者更适合您的需要。

在我们的场景中,我们只是将一个额外的小文本和组合框附加到现有的密码提供程序凭据。我们允许现有的凭据提供程序决定要枚举多少凭据,如何枚举它们,以及如何进行身份验证。我们也让它处理它定义的控件的行为。

凭据提供程序是COM对象,因此可以像任何其他COM对象一样创建和管理它们。在我们的场景中,我们使用CredentialProvider.h中找到的CLSID_PasswordCredentialProvider来实例化提供程序,然后将大部分调用代理到该提供程序,将结果返回为自己的结果。但是,如果我们接收到与特定扩展相关的调用,我们会自己处理这些调用。

由于我们不想限制包装凭证的功能,因此在可能的情况下避免假设是很重要的。例如,我们在扩展中不使用复选框,但是底层凭证可能(如果现在不使用,那么将来可能会使用)。因此,对我们不做任何事情的方法的调用仍然应该传递给包装的凭证。

在某些情况下,我们也处理包装凭证所需的调用。幸运的是,我们可以使用dwFieldID参数来确定引用的字段是属于我们的还是属于他们的。由于我们的示例将控件附加到包装的凭据,因此我们可以执行一个简单的检查,看看该字段是属于我们的还是属于他们的

但是,如果决定在包装凭证中的控件之间插入控件,则需要格外小心地跟踪哪些字段id是您的,哪些是他们的。

对于某些已知的凭据字段,例如密码提供程序密码字段,可以通过检查其凭据提供程序字段描述符的guidFieldType属性来确定其位置。例如,password字段抯CLSID是CPFG_LOGON_password。在shlguid.h中提供了更著名的clsid。

 

默认平铺

当查询凭证提供程序打算返回的磁贴数量时,该提供程序可以指定默认磁贴。尽管从每个单独的凭证提供者的角度来看这很简单,但是开发人员应该记住,LogonUI不一定在所有情况下都将其tile视为默认值。当多个提供程序返回默认磁贴时,最近用于交互式登录的凭据提供程序将收到首选项。换句话说,当两个或多个提供程序返回默认磁贴时,上次用于登录的凭据提供程序指定的磁贴将显示在缩放视图中。此行为不会在远程会话中发生,因为未保存最近使用的凭据提供程序。

凭据提供程序还可以为CredUI使用方案指定默认磁贴。当用户看到CredUI时,此场景中的默认磁贴将接收焦点。CredUI使用与LogonUI相同的逻辑解决多个默认磁贴冲突。凭据提供程序无法确定其他提供程序是否指定默认磁贴。

上次用于成功登录的凭据提供程序提供的默认磁贴不需要与上次登录时使用的磁贴相同。凭据提供程序在枚举默认值时可以自由指定其任何分片。

包装现有凭据提供程序

尽管Microsoft提供了一个包装凭据提供程序示例,但在实现包装的提供程序时,所有第三方都必须格外小心,这一点非常重要。只要实例化包装凭证提供程序的多个实例不会导致问题,包装是一种安全的技术,允许第三方开发人员避免重写代码。例如,如果包装凭据提供程序全局存储任何内容,则创建两个实例时可能会出现问题。微软的收件箱提供商应该可以安全地被第三方包装。

开发人员需要注意,如果凭证提供程序过滤掉包装提供程序的原始实例,包装可能非常危险。在某些情况下,这是可以接受的,但应考虑意外过滤的后果,以避免意外(和不希望的)后果。

编写凭证提供者的IT专业人员可以筛选出域中每个框中的提供者,他们可以根据自己的判断安全地进行筛选。这些管理员拥有在其域中的台式机上的经验。由于受控环境的性质,它们很可能不需要担心冲突的过滤器意外地破坏了它们的机器。安装新凭据提供程序时应遵循最佳做法。在将更改发布到整个域之前,先在分阶段环境中部署。

如果您是一个ISV或OEM,正在设计一个用于部署到您无法控制的桌面的凭据提供程序,那么您将需要更加谨慎地继续。例如,考虑这样一种情况:两个单独的凭据提供程序分别包装和筛选收件箱密码提供程序。假设其中至少有一个在登录前执行影响整个计算机的操作。考虑当用户在同一台计算机上安装这两个假设的凭据提供程序时会发生什么情况。在登录期间,只使用其中一个。在这种情况下,用户可以到达桌面,而无需执行由其中一个凭据提供程序指定的重要操作

总的来说,你应该

-       只有当您明确请求并获得负责安装的管理员的权限时,才能筛选出其他凭据提供程序

-       不筛选出任何内置提供程序(例如,密码提供程序),除非满足以下条件之一

o不筛选收件箱提供程序将导致用户混淆。考虑一下不过滤收件箱提供程序的后果——如果它不会严重影响用户体验(如果用户使用这个收件箱提供程序登录会导致坏问题),那么您可能不需要过滤掉它。

o如果您是OEM或ISV,并且保证您是盒子上唯一的第三方凭证提供商,那么您基本上属于上面的ITPro类别,您应该没有问题。

如果不能保证您是框中唯一的凭据提供程序,则如果筛选任何内置提供程序,可能会引入不稳定性。某些凭据提供程序作者可能会尝试这样做,以强制用户对所有登录使用已安装的第三方凭据提供程序(例如,运行脚本)。依赖用户使用特定的凭据提供程序登录是不好的做法。第三方凭据提供程序作者通常不应假定用户抯系统上不会安装其他凭据提供程序。

 

凭据提供程序体系结构

与GINA不同,凭据提供程序的作者不能也不应该编写代码提供程序来强制在每次登录时运行某些代码。除非绝对保证不会在用户计算机上安装另一个凭据提供程序,否则开发人员应设计凭据提供程序,以提供用户登录的方式,而不保证其凭据提供程序在任何情况下都将用于登录。

凭据提供程序打算并行运行。不应使用包装和筛选来尝试强制执行类似于GINA链接模型的行为,除非保证不会在框上安装其他第三方凭据提供程序

问题

如有任何疑问,请联系credprov@microsoft.com。

附录A-常见问题

一般问题。18岁

序列化。21

安全注意顺序(CTRL+ALT+DEL)22

会话、桌面和凭据提供程序生命周期。22

吉娜移民。23

X86和X64。23

筛选和卸载凭据提供程序。24个

单一登录场景。24

登录用户界面25

信条26

通用域名格式。。26

一般性问题

问:我的凭据提供程序有问题。我可以把我的源代码发送给微软的某个人审阅吗?

答:不。请不要将任何源代码发送到外壳凭据提供程序别名。我们很乐意回答您的问题,并在您开发凭据提供程序时提供帮助,但我们将删除您发送的任何源代码,而不审阅它。发送伪代码是可以的(非代码将提供您尝试做什么的想法),但请不要发送完整的函数定义或类实现。这很重要-因为它保护了我们的合作伙伴,我们的客户(像你!)还有微软。

问:救命啊!我的凭据提供程序被破坏,我无法卸载它!我该怎么办?

答:别慌。重新启动机器并在安全模式下登录(在引导期间按住F8键,弹出一个菜单,您可以在其中选择安全模式)。进入安全模式后,启动regedit并从HKCR和HKLM注销凭据提供程序。现在您应该可以重新启动计算机并在正常模式下登录。

问:我想将第三方唯一标识(如私有认证名称)映射到唯一的Windows凭据。这可能吗?

答:是的,您的凭据提供程序需要收集第三方唯一标识,从第三方帐户目录中检索Windows主体名称,并序列化本地帐户的凭据。此代码应放在ICredentialProviderCredential::GetSerialization()中。

问:我的凭据提供程序是否可以更改其他凭据提供程序磁贴?

答:凭据提供程序应限制自己处理自己的磁贴。

问:如何显示10个以上的凭据提供程序字段?

答:不支持此操作。

问:我在哪里可以找到认证提供者?

答:默认情况下,credentialprovider.h安装在“%systemdrive%\Program Files\Microsoft SDKs\Windows\v6.0\Include”中。

问:我想写一个凭证提供者。我应该从哪里开始?是否有概述文档说明如何编写凭据提供程序?

答:下载我们公布的样品和技术参考。技术参考包含框架的概述(以及解释接口的具体细节)。zip包含一个概述文档,说明如何构建示例。它还包括用于注册和调试代码的指针。

问:是否可以使用Visual Studio.NET 2003为Windows Vista开发凭据提供程序?

答:不需要。凭据提供程序开发需要Windows Vista SDK。Windows Vista SDK需要Visual Studio 8。不支持在Visual Studio.NET 2003中开发凭据提供程序。

问:技术参考是指“瓷砖”。这些到底是什么?是否有可以访问/自定义的基础对象?

答:磁贴对应于ICredentialProviderCredential的实例。您将需要实现此接口(或IConnectableCredentialProviderCredential),以便控制凭据提供程序磁贴的行为和字段。

问:在哪里可以找到凭证提供者的最新技术参考?

答:我们发布供下载的最新文档是凭据提供程序技术参考。

问:我想返回与CPFT_TILE_image的本地用户帐户关联的图像。这张照片在哪里?

答:不支持此操作。

问:我注意到密码提供程序位于AuthUI.dll中。如果取消注册收件箱密码提供程序,删除AuthUI.dll是否安全?

答:不需要。Windows Vista需要AuthUI.dll才能实现其他功能。

问:一般提供者的目的是什么?

答:泛型提供程序序列化包含两个字符串的CPCSS。这些字符串未加密。当CREDUIWIN_Generic标志传递给creduipromptforwindowsccredentials时,泛型提供程序筛选器用于确保只有泛型提供程序在CPU CREDUI中实例化。

问:我想开发自己的智能卡凭证提供商。我应该从哪里开始?如何检测智能卡的移除/插入?

答:您需要从硬件事件凭据提供程序示例开始(请参阅上面的问题)。您的提供商将负责使用SCardGetStatusChange检测智能卡的插入/移除。随着您的开发,其他scardxxapi也会引起您的兴趣。

问:当用户导航到“控制面板”->“经典视图”->“用户帐户控制面板”->“更改您的密码”时,为什么用CPU更改密码实例化凭据提供程序?

答:我们希望为家庭环境中的新手用户提供一种简单且易于发现的方法来更改他们的密码。许多用户习惯于通过此路径更改密码。由于控制面板按设计在标准用户的安全上下文中运行,因此我们不在此控制面板上加载凭据提供程序。

问:我想实现一个凭据提供程序,它响应硬件事件(如智能卡插入)。有样本代码吗?

答:是的,我们发布的一个示例演示了凭据提供程序对(模拟)硬件事件的反应。它提供了一个开始开发硬件事件驱动凭据提供程序的好地方。

问:与RC1相比,Vista RC2版本中的Windows Vista凭据提供程序体系结构、API、错误代码或UI是否有任何更新?它会在即将发布的RTM版本中改变吗?

答:自RC1以来,凭据提供程序接口没有更改。为了帮助我们的合作伙伴和客户有足够的时间来准备WindowsVista,我们的团队从2006年4月开始就非常努力地冻结所有界面。

问:我想显示一个对话框来收集/显示凭据提供程序的信息。我该怎么做?

答:要显示消息框或对话框,您需要检索登录UI抯hwnd。为此,必须调用ICredentialProviderCredentialEvent::OnCreatingWindow()。将对话设置为此hwnd。不支持尝试使用任何其他父hwnd显示对话框。在CPU期间使用任何其他方法显示对话框的凭据提供程序可以在预期的情况下挂起系统。

问:为什么收件箱密码提供程序不包括域下拉列表,就像在WindowsXP中默认的那样?

答:我们在Windows Vista中删除了域下拉列表,原因如下:

-       DsEnumerateDomainTrusts()是我们以前在下拉列表中调用的枚举域的函数,但不能保证返回完整的列表。它旨在尽最大努力,但在某些情况下只返回部分列表

-       调用DsEnumerateDomainTrusts()的任何第三方都希望存储一个缓存的域名列表,以防止用户在其域未返回时产生混淆

-       按设计,此API将通过检查网络上的资源来尝试检索域列表。这导致了性能问题。

-       编写调用此函数的自定义凭据提供程序的第三方应知道,如果调用需要很长时间才能返回,它们可以挂起LogonUI。为了防止这种情况发生,他们的解决方案应该被设计成使调用异步发生。

需要XP中的下拉列表的客户可以创建一个凭证提供程序,在其字段中包含此列表。在大多数组织中,填充此列表的逻辑不需要利用dsenumeratedomaintrust。相反,请调用远程服务或检查计算机上的缓存列表,该列表是通过登录后运行的脚本更新的。

问:哪些Microsoft凭据提供程序随附在Windows Vista上?

答:GenericProvider、NPProvider、PasswordProvider、RasProvider和智能卡凭据提供程序在框中提供。这些提供程序(以及计算机上安装的任何第三方提供程序)列在“HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential providers”和“HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\PLAP providers”下。

问:如果在cpu CREDUI中序列化后遇到错误,则不调用我的ICredentialProviderCredential::ReportResult实现。这是虫子吗?

答:不,这不是虫子。在CPU指令中未调用ReportResult。

问:我的凭据提供程序尝试通过返回默认凭据并将pbAutoLogonWithDefault设置为true来自动提交。当不正确的凭据被序列化时,我的磁贴会不断尝试自动提交并进入一个无休止的循环。发生了什么?

答:解决这个问题有两种不同的方法。

-       您可以创建一个内部结构来跟踪自动提交凭据的尝试,如果失败,请在ICredentialProviderCredential::ReportResult中检查它。从那里你可以改变你的结构,以表明你不想自动提交,或采取一些其他行动。

-       Another approach to the problem is to have your Credential Provider enumerate more than one tile. When GetCredentialCount is called, designate a default tile and attempt to autologon using it. In the event of failure, the user will see the second (and likely empty) credential tile. This seems less intuitive than the alternative (re-enumerating on autologon failure), however you will find it is simpler to code.

Q: I can&apos;t seem to set the interactive states of my Credential Provider fields to read-only or disabled. I attempt to specify CPFIS_READONLY and CPIFS_DISABLED but this doesn&apos;t seem to work. What&apos;s wrong?

A: Nothing is wrong with your code. CPFIS_READONLY and CPFIS_DISABLED are not implemented for Windows Vista. We plan to add support for these interactive states in a future release.

Q: How can I get my Credential Provider to respond to AutoAdminLogon?

A: Set HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon 揂utoAdminLogon� to 1, filter the Password Provider, and submit a credential to autologon with.

Q: I want to configure my Credential Provider to perform autologon. How may I accomplish this?

A: In order to do this, you must set configure the machine for auto logon, configure your Credential Provider to specify a default credential, and set pbAutoLogonWithDefault to true. To set configure your machine for autologon, you must set the following registry key

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]

�AutoLogonAdmin�=�1�

牋�

Q: I would like to hide and reveal one a field in my Credential Provider dynamically. How can I do this?

A: When your tile is advised, use methods exposed by ICPCE. When your tile is not advised, you must perform a full re-enumeration in order to change a field抯 state from hidden to unhidden.

Q: I downloaded the Beta 2 samples and tried to compile them. I get an error trying to link to bufferoverflowu.lib. What should I do?

A: Changes in the build and SDK exposed this problem after we released the Beta 2 samples. We will release new versions of the samples at RTM. Check on msdn to see if the updated versions are available. You may also correct the problem with the samples you currently have by taken the following steps...

-       Comment out the line �#include <winres.h>� in resource.rc

-       In the solution explorer, right-click the node below the top-level solution and select Properties from the context menu

-       A dialog will open

-       In the left-hand tree control, navigate to Configuration Properties => Linker => Input

-       Remove bufferoverflowu.lib

-       Add gdi32.lib, ole32.lib, user32.lib

Serialization

Q: My application respects the GP Setting indicating smartcard must be used for domain credentials. I don&apos;t want to uninstall or filter the Password Provider, but I don&apos;t want password providers to enumerate in CredUI. How can I prevent non-smartcard providers from enumerating?

A: Simply stated, CredUIPromptForCredentials has no way to specify "smartcard only". Since both the Smart Card Provider and the Password Provider recognize the Kerberos authentication package, passing in Kerberos as the auth package will not prevent the Password Provider from enumerating credentials. To work around this limitation, your application must pass a partially filled Smart Card credential blob as well as the flag CREDUIWIN_IN_CRED_ONLY when calling CredUIPromptForWindowsCredentials. Refer to the Credential Provider Samples for additional information. Alternatively, if your credential provider is not capable of serializing Kerberos certificate credentials, it is good practice to register a filter and prevent your credential provider from enumerating tiles when this policy setting is enabled.

 

Secure Attention Sequence (CTRL+ALT+DEL)

Q: How can I initiate Ctrl+Alt+Del from my Credential Provider?

A: This is not supported. Requiring Ctrl+Alt+Del (CAD) for interactive logon is intended to defeat spoofing (for the purposes of credential harvesting). A Credential Provider generated substitute for this sequence does not provide protection against spoofing. Treating arbitrary hardware events (such as USB insertion, Smartcard insertion, etc) does not initiate a transition to the secure desktop in all scenarios. As a result, it&apos;s possible for an application running with standard user privileges to spoof the logon screen and steal a users credentials. Organizations who consider CAD to be inconvenient are able to disable the Group Policy setting requiring CAD during interactive logon. We encourage organizations to carefully consider the security implications of disabling this group policy setting before doing this.

 

Sessions, the Desktops, and the Credential Provider Life-Cycle

Q: Is my Credential Provider loaded in Session 0?

A: Your Credential Provider is instantiated in the same session as LogonUI. In Windows Vista, Session 0 is reserved for services and is almost never visible. When it is visible, LogonUI is not. The particular TS session your Credential Provider is instantiated is generally not a useful piece of information.

Q: Which desktop does LogonUI instantiate my Credential Provider on?

A: TS Sessions contain a single Window Station. This Station has may contain multiple desktops. LogonUI loads your Credental Provider on the Winlogon desktop.

Q: Is it permitted to use my Credential Provider to run SYSTEM applications on the Winlogon Desktop?

A: Although Windows Vista does not explicitly prevent SYSTEM applications from running on the Winlogon Desktop, this practice is not recommended and is strongly discouraged. SYSTEM privileges may be used to gain access to any resource on the computer. Running SYSTEM applications on the winlogon desktop exposes security vulnerabilities.

Q: Do I need to worry about malware running on the user desktop trying to sniff key strokes entry on the Winlogon Desktop?

A: Desktops are an isolation boundary for windows messages. Unless the TCB is compromised, your Credential Provider should not need to worry about this problem.

Q: Is it permitted to use my Credential Provider to run USER applications on the Winlogon Desktop?

A: USER applications may not run on the Winlogon Dekstop.

Q: How long does my Credential Provider exist?

A: In order to ensure forward compatibility with future versions of Windows, we recommend architecting your Credential Provider to collect and serialize credentials. Providers that depend on being created and destroyed at a specific time are not guaranteed to be forwards compatible.

Q: Does my Credential Provider exist throughout an entire TS session?

A: No. Credential Providers are created when necessary and then destroyed. LogonUI and CredUI both destroy Credential Provider objects before exiting.

 

GINA Migration

Q: My organization used a custom GINA in a previous version of Windows. How do Credential Providers interact with GINA?

A: They do not. Beginning with Windows Vista, Gina抯 are no longer supported. Your solution will need to be re-factored in order to work properly on Windows Vista.

Q: I used biologon.dll with my GINA in Windows XP. Will this work in Windows Vista?

A: No. Biologon.dll does not work with Windows Vista.

Q: Are notification packages supported in Windows Vista?

A: Winlogon Notification Packages are no longer supported. Please refer to the published whitepaper Winlogon Notification Packages Removed Impact on Windows Vista Planning and Deployment.doc.

Q: In previous versions of Windows Vista, I wrote a custom GINA and registered a custom Winlogon Notification Package to detect events such as StartShell and StopScreenSaver. How can I use this in Windows Vista?

A: If you wish take action on a state transition in Windows Vista, you will need to use SENS or SCM notifications. Both solutions can be used on Windows Vista and earlier versions.

Q: My GINA used to load an application after the user successfully logged on. How can I do this with my Credential Provider?

A: Credential Providers are responsible for gathering information for the purposes of authentication and packaging that information as a credential blob. Credential Provider should not be designed to start applications to run on a user desktop on behalf of a specific user. In a perfect world the Credential Provider will already have been destroyed by the time applications are allowed to start as the logged on user. Technologies such as startup scripts are more appropriate for this purpose.

X86 and X64

Q: I downloaded the latest SDK, but I don&apos;t see the libraries I need to build 64-bit Credential Providers. Where can I find these libraries?

A: On x86 machines, 64-bit libraries are not installed by default. You must specifically select to install them during setup. Do this by drilling down through the nodes of the tree control the optional components.

Q: In Windows Vista x64, is a 32-bit CSP required to support custom CAPI?

A: When a 32-bit application, running on a 64-bit machine, calls CredUIPromptForWindowsCredentials, 32-bit versions of the Credential Providers are needed in all scenarios where secure desktop prompting is not enabled. Any 32-bit CAPI application will also use the 32-bit CSPs and card modules in this case. 64 bit versions of the Credential Providers, CSPs, and card modules are needed to support this scenario when secure prompting is enabled.

Q: Does the windows logon process use the 32 or 64 bit version of the CSP for smart card logon?

A: LogonUI is always native.

You will need to compile a 64 bit version of your Credential Provider in order to support CPUS_LOGON on machines running a 64-bit version of Windows Vista.

Q: On Windows x64 bit platform, if an application using CAPI (for smart card logon for example) is running in 32 bit, will the WOW64 transparently redirect the CSP calls to 64 bit version of registered CSP or should two versions of the CSP be registered in the system, one for 32 and one for 64 bit applications?

A: Dlls like credential providers (CPs) and CSPs (and card modules) need to match the version of their host (the exe). 64-bit exes load only 64-bit dlls. 32-bit exes load only 32-bit dlls. You may need 32-bit versions of the each component on 64-bit platforms in order to support WOW64.

Filters and Uninstalling Credential Providers

Q: Does the Shell Credential Provider team publish sample code illustrating how to implement ICredentialProviderFilter?

A: No. Please refer to the Credential Provider Technical reference for details regarding authoring a Credential Provider Filter.

Q: My implementation of ICredentialProviderFilter is not loaded in SAFE mode. Is this a bug? Is there a way to run my Filter in SAFE mode?

A: This is not a bug. SAFE mode is intended to serve as a workaround in order to correct repair Operating Systems malfunctioning due to incorrectly configured components such as device drivers. By default, only the in-box Password Provider is loaded in SAFE mode. The in-box Smart Card Provider is also available if the machine is booted into SAFE mode with networking. This provides a fallback in case of a bad error. To over-ride the fallback logic and force logonUI to load Credential Provider filters in SAFE Mode, create and set the following registry key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers]

揚rohibitFallbacks�=dword:1

Important Note: 燘y setting this registry key, you will explicitly override the fallback safety mechanism Windows Vista supplies to troubleshoot configuration errors and malfunctioning Credential Providers. Users may be blocked from logon in the event of Credential Provider failure.

Q: Is it possible to de-register the in-box Credential Providers?

A: Yes, these may be de-registered just like any other COM object. They are registered under HKEY_CLASSES_ROOT\CLSID. Please refer to CredentialProvider.idl for a complete list of Credential Providers which ship in-box and corresponding CLSIDs.

Important note: By default, Windows Vista requires the Password Provider and Smart Card Provider to boot into SAFE mode. After de-registering Credential Providers on a machine, you will need to prohibit fallbacks (see question above) in order to load new Credential Providers in SAFE mode.

 

Single Sign On Scenarios

Q: I want to create a VPN connection after authentication. How can I do this with a Credential Provider?

A: Credential Providers are destroyed after logon. Connecting to a VPN after logon requires a network provider.

Q: 營s it possible to write a single sign on Credential Provider supporting 802.1x Authentication + Windows logon? A: Yes. IConnectableCredentialProviderCredential, which inherits all methods from ICredentialProviderCredential, is suitable for this scenario. Your Credential Provider should collect credentials from the user and use them to connect to the a WAP through IConnectableCredentialProviderCredential::Connect().If the connection is successful, attempt to Serialize credentials for local machine logon using GetSerialization().

Note: Connect() will always be called before GetSerialization().

Q: Do you offer a sample Credential Provider illustrating this?

A: No.

 

Logon UI

Q: May I add items to the security options screen?

A: This is not supported.

Q: Will a CP implementing CPUS_LOGON work in TS?

A: Yes it will, since LogonUI in remote sessions loads CPs normally.

Q: I抎 like to display a common control on Logon UI that doesn抰 exist in the control set defined by the Credential Provider. Is this possible?

A: This is not recommended or supported.

Q: I抳e used ICredentialProviderCredentialEvents::OnCreatingWindows() to retrieve LogonUI抯 HWND, and display a dialog parented to LogonUI. My dialog doesn抰 appear with Glass and aero-themed menus. Why not?

A: The theme service is not enabled on the Winlogon Desktop. The theme service provides visual styles for Windows and applications. It is not possible to use glass, specify fonts, or specify colors for your dialog without the theme service.

Q: How can I change the background of LogonUI?

A: This is not supported in Windows Vista.

Q: How do I write my Credential Provider to autosubmit credentials when it has all the required information?

A: Your Credential Provider may autosubmit Credentials in two ways.

-       Specify a default Credential and set pbAutoLogonWithDefault to true in response to GetCredentialCount()

-       Set pbAutoLogon to true in response to SetSelected()

Both of these methods will cause a call to GetSerialization (and Connect() if the credential is an instance of IConnectableCredentialProviderCredential). To initiate auto-submission of credentials at a an arbitrary point in time, your provider may call ICredentialProvider::CredentialsChanged. This call will force a full re-enumeration of credential tiles. When LogonUI calls ICredentialProvider::GetCredentialCount, specify a default tile and set the value of pbAutoLogonWithDefault to true (as mentioned above).

Note: Developers should be aware that race conditions may exist if another provider installed on the machine also requests to autologon with the default during this call. Please refer to the technical reference for a detailed explanation of the logic LogonUI uses to decide which credential to submit to Winlogon in this case.

CredUI

Q: What is CPUS_CREDUI?

A: Windows Vista introduces a new public API for credential collection, CredUIPromptForWindowsCredentials. To see an instance of this API being used to collect credentials, open the remote desktop client (mstsc.exe), specify a target machine, and click &apos;connect&apos;. The Windows Security dialog that appears loads Credential Providers in the CPUS_CREDUI scenario.

Q: My application calls CredUIPromptForCredentials. How can I leverage Credential Providers using this API?

A: CredUIPromptForCredentials is very different than CredUIPromptForWindowsCredentials. The legacy API (CredUIPromptForCredentials) is not aware of Credential Providers. In order to collect credentials within your application using Credential Providers, you must revise your application&apos;s code to call CredUIPromptForWindowsCredentials.

Q: How can I call CredUI and specify it only load a specific Credential Provider?

A: In general, this is not supported. Credential Providers aim to support credential agility. This means that if

an application accepts Kerberos credentials, any credential provider that knows how to serialize Kerberos credentials will be able to be used.

Q: How can I specify my Credential Provider to load in the User Account Control Prompt?

A: If your credential provider supports CPUS_CREDUI, it will be available in the UAC prompt. To support the CredUI usage scenario, your provider must return S_OK� when CPUS_CREDUI is passed in through SetUsageScenario(). Your provider must indicate it will enumerate at least one tile in in response to GetCredenitalCount() and then supply the credential in GetCredenialsAt(). Under normal circumstances, if your provider behaves in this way, your tile will appear in the UAC prompt.

Note: Please refer to Group Policies related to the UAC prompt. Specifically, if you intend for your credential provider to appear in the UAC prompt, it should respect the Group Policy setting 揈numerate administrator accounts on elevation�. Please refer to this GP for more information.

Q: How can I differentiate between CPUS_CREDUI for credential collection in TS and credential collection in the UAC prompt?

A: In general, we encourage Credential Provider authors to write their CP such that no differentiation in these two states is necessary. Enumerating a default (or &apos;empty&apos;) tile in CREDUI_CPUS is a good practice. Developers may examine the flags passed in ICredentialProvider::SetUsageScenario to gather more context regarding the scenario at run time. Specifically, CREDUIWIN_ENUMERATE_ADMINS will always be passed in CPUS_CREDUI when tiles are requested for the UAC dialog. Note: Referring to UAC specifically in your credential provider when you see CREDUIWIN_ENUMERATE_ADMINS is bad form since this flag may be passed during credential collection with CredUI in scenarios other than the UAC dialog.

COM

Q: How may I call methods exposed by ICPCE?

A: Methods exposed by ICPCE may only be called when your provider is advised. Your provider is advised around ICPC calls. Your provider is responsible for storing the ICPCE pointer while advised, and should null this pointer when unadvised. Do not pass the ICPCE pointer to other threads and attempt to call these methods. The ICPCE interface must be called from the credential provider抯 thread.

 

Q: What apartment threading model should I write my CP to run in?

A: CPs must be written to run STA.

Q: May I call the methods on the ICPE interface asynchronously?

A: Yes, the methods on the ICPE interface can be called asynchronously.

Q: Do credential providers ever have to worry about reentrancy?

A: No. There are no supported scenarios in which Credential Providers need to worry about reentrancy.

-       A separate TS session (with individual instances of Winlogon and LogonUI) is used each time a user is prompted for logon credentials.

-       Calls to CredUIPromptForWindowsCredentials return after a credential provider successfully serializes credentials.

Q: Can CPs be implemented in managed code through COM interop? Or must they be native code?

A: Microsoft recommends all code running in system context be implemented in native code. We do not support Credential Providers written in managed code.

杂记-CredentialProvider(翻译)相关推荐

  1. 怪哉翻译软件测试,翻译怪哉虫文言文

    翻译怪哉虫文言文以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 1. 翻译文言文怪哉虫 汉武帝有一次到甘泉宫去,在路上看 ...

  2. (大集合)Linux进程和线程的基本编程、通讯和例程【杂记】

    Linux 进程 和 线程 的基本 编程.通讯 和 例程 注:[杂记]系列为日常网搜资料的堆砌而积累成之.如有错误恭谢指出.标识为"原创"其实不完全是,只是多引用再整理和加上自己的 ...

  3. Java开发和测试开发面试杂记

    文章目录 重载和重写 多态 泛型 抽象类和接口,继承的区别 进程和线程的区别 @Resource注解 bean的生命周期 微信聊天测试 时间复杂度 int和Integer的区别 HTTP和HTTPS的 ...

  4. c语言的离骚,高中必修一语文离骚翻译及赏析

    我揩着眼泪啊声声长叹,哀叹人民的生活多么艰难.我虽爱好修洁严于责己,可早晨进谏晚上即遭贬.下面给大家带来一些关于高一必修一语文离骚翻译及赏析,希望对大家有所帮助. 离骚翻译: 我揩着眼泪啊声声长叹,哀 ...

  5. 学习方法和自我管理杂记

    学习方法和自我管理杂记 1. 两种学习方法 2. 马拉松式学习与技术人员的成长性 3. 进阶之路 4. 从拖延到高效,我推荐这 7 本书 7. How to read source code 8. 技 ...

  6. 面试杂记:三个月的面试回忆录(携程、腾讯等)

    面试杂记:三个月的面试回忆录(携程.腾讯等) 前话: 话说2年的创业过去了,随着项目的盈利能力越来越弱,基于家庭的压力,不得不暂停创业的步伐,回归到找工作的路程. 于是,就有了这两三个月长短性找工作的 ...

  7. Mysql函数group_concat、find_in_set 多值分隔字符字段进行数据库字段值翻译

    Mysql函数group_concat.find_in_set进行数据库字段值翻译 场景 配方表:记录包含的原料 sources表示原料,字段值之间用逗号分隔 原料表:对应原料id和原料名称 现需要查 ...

  8. “Attention is All You Need 翻译

    <p><img src="output_0_0.png" alt="png"></p> "Attention is ...

  9. 基于PyTorch的Seq2Seq翻译模型详细注释介绍(一)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qysh123/article/deta ...

最新文章

  1. python 将列和索引的值变换_【编辑小组成长日记】Python学习第二期
  2. CSDN 文章标题含非法字符
  3. 【python图像处理】彩色映射(续篇)
  4. python中修改列表元素的2种方法
  5. python如何绘制曲线图_只会柱状图、饼状图、折线图怎么行,来用Python画个热力图...
  6. 【转】C#中的命名空间namespace全解
  7. Django 2.0 学习(12):Django 模板语法
  8. python语法训练_18-04-17回顾: python3语法+刻意训练
  9. 使用其它模块的头文件
  10. 树立榜样、褒奖开源领域领袖人物、杰出贡献人物
  11. jqgrid本地数据例子_FMS财务系统:日常数据核对与处理
  12. java 实现word转txt
  13. 利用matlab实现h 控制,利用matlab实现H-infinity鲁棒控制.doc
  14. python实例02,__str__只能返回字符串
  15. fantastic-matplotlib:案例集合:
  16. 安卓APP自动更新功能实现
  17. 2016第1篇--Python查看微信被删好友
  18. ACM学习:例题完成总结与期中心得
  19. Java时间片轮转(简单模拟实现,适合初学者)
  20. CSS精灵图(sprite)

热门文章

  1. CSS3 3D空间转换
  2. php集群管理自动采集cns,CNS平台集成Expect自动化脚本配置功能
  3. 试试kaggle竞赛:辨别猫狗
  4. 基于PHP语言Laravel+Layui后台代码生成工具
  5. 【React生命周期】
  6. SpringBoot+自定义注解实现多数据源配置
  7. 嵌入式的应用领域、现状及未来趋势
  8. 每天10个前端小知识 【Day 13】
  9. Excel合并单元格如何实现组内合并单元格后排序
  10. OpenCV教程(转自:浅墨_毛星云博客)