现在的位置: 首页 > 综合 > 正文

Credential Provider

2013年12月01日 ⁄ 综合 ⁄ 共 2150字 ⁄ 字号 评论关闭

Windows操作系统的登录

WinXP利用GINA机制来登录,从Vista开始采用新的登录机制,名为Credential Provider. 
 
在 Windows Vista 之前的环境中,每个会话都有一个 winlogon 实例,它负责控制该会话的交互式登录序列,它运行在Session 0. 计算机上已注册的 GINA 加载到 winlogon 进程空间中。(还可能加载一个称作“GINA 链接”的配置,但测试和支持这样的复杂配置很困难。)最后,GINA 调用 LogonUser 以及相关的身份验证 API。
 
在 Windows Vista 以后的系统中,Session 0 不再用于交互式登录.这有利于提高安全性,因为现在已有一个会话边界将所有的计算机进程与各个用户的进程分隔开来。此外,现在对内核全局命名空间的控制也更加严格,因为默认情况下由用户应用程序创建的对象已不在内核全局命名空间之内。
 
除Session 0 之外的每一个Session仍会有一个 winlogon 实例, 已通过新的 LogonUI 进程加载。
在由哪个组件负责显示登录图形界面方面也有一个重要的改动。以前,这是由 GINA 来处理的,因此,显示界面的工作可能一直由第三方组件来完成。在新的体系结构中,这是由操作系统的一个内置组件 LogonUI 来负责完成的。

新的Credential Provider机制由2部分组成

ICredentialProvider : 

以ICredentialProvider 为父类的Provider对象,初始化时LogonUI会调用SetUsageScenario 函数来初始化环境,然后调用
GetCredentialCount,GetCredentialAt 来得到此Provider下的所有的Credential对象,再调用GetFieldDescriptorCount,GetFieldDescriptorAt来得到Credential的UI描述.注意UI描述对于同一个Provider下的Credential都是相同的.

ICredentialProviderCredential : 

以ICredentialProviderCredential 为父类的Credential对象,它表现为界面上某一个ICON区域.通过它,可以得到界面每个元素的类型和值.

ICredentialProviderFilter :

以ICredentialProviderFilter 为父类的Credential对象,它是一个过滤对象,可以指定在系统登录的时候,那些Provider是有效的,通过它可以实现只保留系统中一个或几个特殊Provider的效果.

Credential Provider注册

注册表结构类似如下形式

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{F617AF08-2856-419c-B4E5-2889C6B71EA9}]
@="SSCredProvider"
[HKEY_CLASSES_ROOT\CLSID\{F617AF08-2856-419c-B4E5-2889C6B71EA9}]
@="SSCredProvider"
[HKEY_CLASSES_ROOT\CLSID\{F617AF08-2856-419c-B4E5-2889C6B71EA9}\InprocServer32]
@="E:\\Sources\\SourceRoot\\trunk\\win32\\bin.debug\\SSCredProvider.dll"
"ThreadingModel"="Apartment"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{F617AF08-2856-419c-B4E5-2889C6B71EA9}]
@="SSCredProvider"

有几点需要注意:

1. Credential一般存在于Provider中,必须动态创建,利用COM的AddRef和Release机制来操作其生命周期.
2.Credential通过GetSerialize来登录系统,调用Lsa系列函数,例如LsaConnectUntrusted等,结果如果为NTSTATUS,可以调用HRESULT_FROM_NT来判断是否成功,HRESULT要用SUCESSED宏,而不能直接比较是否等于S_OK.
3.关于FieldDescriptor.每个Provider下的Credentials共享相同的FieldDescriptor,即一个Credential有几个UI元素,其余的Credentials也必须有相同的个数,但是每个Credentials可以通过GetFieldState 来调整自己的UI元素的状态.

抱歉!评论已关闭.