ADsOpenObject 函数和 IADsOpenDSObject::OpenDSObject 方法用于在指定备用凭据时以及需要数据加密时绑定到目录服务对象。
应尽可能使用调用线程的凭据。 但是,如果使用备用凭据,则必须使用 ADsOpenObject 函数或 IADsOpenDSObject::OpenDSObject 方法。 如果使用备用凭据,请务必不缓存密码。 可以通过为第一个绑定作指定用户名和密码,然后仅在后续绑定中指定用户名来执行多个绑定作。 只要满足以下条件,系统就在第一次调用上设置会话,并在后续绑定调用上使用同一会话:
- 每个绑定操作中的用户名相同。
- 在每次绑定操作中实现无服务器绑定或绑定到同一服务器。
- 通过保留其中一个绑定操作中的对象引用来保持打开的会话。 释放最后一个对象引用时,会话将关闭。
ADsOpenObject 和 IADsOpenDSObject::OpenDSObject 使用 Windows NT 安全支持提供程序接口(SSPI),以灵活地使用身份验证选项。 使用这些接口的主要优点是向 Active Directory 客户端提供不同类型的身份验证,并加密会话。 目前,ADSI 不允许传入证书。 因此,可以使用 SSL 进行加密,然后使用 Kerberos、NTLM 或简单的身份验证,具体取决于如何在 dwReserved 参数上设置标志。
在 ADSI 中不能请求一个特定的 SSPI 提供程序,但是您总是会得到最优先的协议。 对于 Windows 客户端绑定到运行 Windows 的计算机,协议为 Kerberos。 对于网页,不允许使用证书进行身份验证是可以接受的,因为身份验证是在运行网页之前进行的。
尽管 Open操作允许您指定用户和密码,但不应这样做。 而是不要指定任何凭据,并隐式使用调用方安全上下文的凭据。 若要使用调用方的凭据通过 ADsOpenObject 或 IADsOpenDSObject::OpenDSObject绑定到目录对象,请为用户名和密码指定 NULL。
最后,若要绑定而不进行身份验证,则请使用 ADS_NO_AUTHENTICATION 标记。 无身份验证表示 ADSI 尝试作为匿名用户绑定到目标对象,并且不执行任何身份验证。 这相当于在 LDAP 中请求匿名绑定,并指示所有用户都包含在安全上下文中。
如果身份验证标志设置为零,ADSI 将执行简单绑定,以纯文本形式发送。
谨慎
如果在未指定身份验证标志的情况下指定用户名和密码,则用户名和密码以纯文本形式通过网络传输,这是一个安全风险。 请勿在未指定身份验证标志的情况下指定用户名和密码。
例子
以下 Visual Basic 代码示例演示如何使用 IADsOpenDSObject::OpenDSObject 方法。
Const ADS_SECURE_AUTHENTICATION = 1
Dim openDS As IADsOpenDSObject
Dim usr As IADsUser
Set openDS = GetObject("LDAP:")
openDS.OpenDSObject("LDAP://CN=jeffsmith,DC=fabrikam,DC=com",
vbNullString,
vbNullString,
ADS_SECURE_AUTHENTICATION)
以下C++代码示例演示如何使用 ADsOpenObject 函数。
IADs *pObject;
HRESULT hr;
hr = ADsOpenObject(L"LDAP://CN=jeffsmith,DC=fabrikam,DC=com",
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)&pObject);
if(SUCCEEDED(hr))
{
// Use the object.
// Release the object.
pObject->Release()
}
IADsOpenDSObject 接口也可以在C++中使用,但它复制 ADsOpenObject 函数。
以下C++代码示例演示如何使用 IADsOpenDSObject 接口执行与上面的代码示例相同的绑定作。
IADsOpenDSObject *pDSO;
HRESULT hr;
hr = ADsGetObject(L"LDAP:", IID_IADsOpenDSObject, (void**)&pDSO);
if(SUCCEEDED(hr))
{
IDispatch *pDisp;
hr = pDSO->OpenDSObject(CComBSTR("LDAP://CN=jeffsmith,DC=fabrikam,DC=com"),
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
&pDisp);
if(SUCCEEDED(hr))
{
IADs *pObject;
hr = pDisp->QueryInterface(IID_IADs, (void**) &pObject);
if(SUCCEEDED(hr))
{
// Use the object.
// Release the object.
pObject->Release();
}
pDisp->Release();
}
pDSO->Release();
}