首页 > 解决方案 > 使用 ADO 从 Access VBA 中检索用户成员资格以执行 LDAP 查询

问题描述

我正在使用 Microsoft Access 中的 VBA 查询 Active Directory。与网上发布的许多示例一样,我使用 ADO 连接来执行 LDAP 查询。我可以成功提取一些属性,如sngivenNamemailproxyAddresses以及一些其他的 MS Exchange 属性,如msExchExtensionAttribute##属性。

现在我正在尝试查询该memberOf属性并且除了我自己之外没有收到任何用户的返回值。我可以在 Outlook 中轻松查看其他用户的组成员身份,或者通过使用 Windows Active Directory 搜索工具进行搜索来查看谁是组成员。对我来说听起来像是权限问题,所以我挖掘了我的连接字符串。我怀疑我是在匿名提出请求,因为我没有指定用户名或密码。

我正在尝试确保我使用 Windows 身份验证,并且它必须能够由普通用户运行(因为我也在这个域中),因此没有管理员权限可以执行此操作。

一些基本的翻找使我相信将连接属性的集成安全属性设置为SSPI应该这样做。但是,这行不通。在这一点上,我只是想让它工作,所以该函数只返回一个用于调试的字符串,但我最终会返回一个数组或对象。

这是我到目前为止所得到的:

Function GetMembershipFromUsername(uname As String) As String
    'Get the domain root
    Dim root As IADs
    Set root = GetObject("LDAP://RootDSE")

    'Set the query parameters
    Dim base as String, fltr as String, attr as String, scope as String
    base = "<LDAP://" & root.Get("defaultNamingContext") & ">"
    fltr = "(&(objectCLass=user)(objectCategory=Person)(sAMAccountName=" & uname & "))"
    attr = "sAMAccountName,memberOf"
    scope = "subtree"

    'Connect to the LDAP server
    Dim conn As ADODB.Connection
    Set conn = CreateObject("ADODB.Connection")
    conn.Provider = "ADsDSOObject"
    conn.Properties.Item("Integrated Security").Value = "SSPI"
    conn.Open "Active Directory Provider"

    'Create LDAP command object
    Dim cmd As ADODB.Command
    Set cmd = CreateObject("ADODB.Command")
    Set cmd.ActiveConnection = conn

    'Build command
    cmd.CommandText = base & ";" & fltr & ";" & attr & ";" & scope

    'Execute and return info
    Dim rs as ADODB.Recordset, vi as Variant, ml as String
    Set rs = cmd.Execute
    If rs.RecordCount > 0 Then
        For Each vi In rs.Fields(1).Value
            ml = ml & vi & Chr(10)
        Next vi
    End If
    rs.Close

    conn.Close

    GetMembershipFromUsername = ml
End Function

我是否遇到了权限问题,我是否仍在以某种方式匿名提出请求,或者我是否犯了一些其他错误,只能让我获得自己的组成员资格?

标签: vbams-accessactive-directoryldapado

解决方案


应该使用 IADsOpenDSObject 接口而不是 IAD 来使用安全上下文而不是当前请求绑定的用户绑定到 AD对象

IADsOpenDSObject 接口旨在为绑定到底层目录存储中的对象提供安全上下文。它提供了一种指定客户端凭据的方法。当您必须为任何目录服务中的身份验证提供一组凭据时,使用此接口绑定到 ADSI 对象。

您需要使用GetObject()方法创建对 IADsOpenDSObject 的引用,就像使用 IADs 接口一样。然后,您可以调用OpenDSObject()允许使用任意凭据绑定到 ADSI 对象的方法:

Dim ds As IADsOpenDSObject 
Set ds = GetObject("LDAP://RootDSE")

Dim root As IADs
Set root = ds.OpenDSObject(dn, username, password, ADS_SECURE_AUTHENTICATION)

最后一个参数是一个身份验证标志(请参阅 参考资料ADS_AUTHENTICATION_ENUM),它决定使用哪个身份验证过程。


推荐阅读