是否有可能获取LDAP字段并将其存储在SQL数据库中?



我的应用程序中已经有了LDAP身份验证。我如何去获取字段,如'给定名称'或'姓氏'从LDAP存储和存储在SQL数据库中?

此外,是否也有可能授权用户只有当LDAP 'uid'匹配'uid'存储在本地数据库?

任何帮助都会很感激。谢谢。

可以使用SQL Server本身,您可以设置一个链接服务器

注意:您可以以这种方式返回的默认最大行数是1000,因此请尽可能限制您的搜索。

添加链接服务器

您可以执行下面的sql存储过程来添加链接服务器,请确保用有效的登录信息替换第二条语句中的@rmtuser和@rmtpassword字段:

EXEC master.dbo.sp_addlinkedserver 
    @server = N'ADSI', 
    @srvproduct=N'Active Directory Services 2.5', 
    @provider=N'ADsDSOObject', 
    @datasrc=N'adsdatasource', 
    @provstr=N'ADSDSOObject'
EXEC master.dbo.sp_addlinkedsrvlogin
    @rmtsrvname=N'ADSI',
    @useself=N'False',
    @locallogin=NULL,
    @rmtuser=N'DOMAINlogin',
    @rmtpassword='password'

选择LDAP数据

您可以使用OPENQUERY函数来查询LDAP,例如:

SELECT distinguishedName, sAMAccountName, objectGUID, objectSid, givenName, sn
FROM OPENQUERY(ADSI, 
    'SELECT sn, givenName, objectSid, objectGUID, sAMAccountName, distinguishedName FROM ''LDAP://DC=domain,DC=net'' WHERE objectClass=''User'' AND sAMAccountName = ''nouptime'''
    )
AS derivedtbl_1

注意:OPENQUERY中的select语句必须是连续的一行,不能换行,否则会抛出错误。

LDAP服务器地址

如果您的域名dns地址(可以在命令提示符ipconfig在"连接特定的dns后缀"下找到)是corp.domain.net那么它是 " LDAP://DC=corp,DC=domain,DC=net " 或者只是domain.net " LDAP://DC=domain,DC=net "

查找要选择的字段

如果您要在上面的select语句中使用全列操作符(*),您将获得objectClassUser的所有可能字段,您可以对Groups执行相同的操作,以便发现您需要返回哪些字段,字段名称区分大小写。

objectSid是我怀疑你想要的字段,这可以存储在SQL Server作为varbinary(256)。

过滤LDAP数据

您还可以通过使用userAccountControl字段(列表)来检查帐户的状态,这是一个位字段,您可以在OPENQUERY函数中使用LDAP_MATCHING_RULE_BIT_OR进行位检查,该函数为1.2.840.113556.1.4.804,使用上面的语句的示例:

SELECT distinguishedName, sAMAccountName, objectGUID, objectSid, givenName, sn
FROM OPENQUERY(ADSI, 
    'SELECT sn, givenName, objectSid, objectGUID, sAMAccountName, distinguishedName FROM ''LDAP://DC=domain,DC=net'' WHERE objectClass=''User'' AND sAMAccountName = ''nouptime''' AND (''''userAccountControl:1.2.840.113556.1.4.804:''''<>2)
    )
AS derivedtbl_1

只要在LDAP中没有禁用该帐户,该语句将返回用户' nuptime '的详细信息。

插入,更新(Upserting)本地LDAP数据缓存

当我使用SQL Server 2008R2时,我可以使用MERGE语句在一个语句中更新此表,例如:

MERGE INTO tblADUsers
    USING (
        SELECT 
            objectSid, 
            LOWER(sAMAccountName) AS sAMAccountName, 
            givenName, 
            sn,
            LOWER(mail) AS mail,
            CURRENT_TIMESTAMP AS DateAdded 
        FROM OPENQUERY(ADSI, 'SELECT mail, sn, givenName, sAMAccountName, objectSid FROM ''LDAP://DC=corp,DC=domain,DC=net'' WHERE objectClass=''User'' AND  (''userAccountControl:1.2.840.113556.1.4.804:''<>2) ')
        AS derivedtbl_1) AS adsoruce
ON tblADUsers.sAMAccountName = adsoruce.sAMAccountName
WHEN MATCHED THEN
    UPDATE SET objectSid= adsoruce.objectSid
        ,givenName = adsoruce.givenName
        ,sn = adsoruce.sn
        ,mail = adsoruce.mail
        ,dtUpdated = getdate()
        ,dtDeleted = NULL
WHEN NOT MATCHED BY SOURCE THEN
    UPDATE SET dtDeleted = getdate()
WHEN NOT MATCHED THEN
    INSERT (objectSid, sAMAccountName, givenName, sn, mail, dtDateAdded)
    VALUES (
            adsoruce.objectSid
            ,adsoruce.sAMAccountName
            ,adsoruce.givenName
            ,adsoruce.sn
            ,adsoruce.mail
            ,adsoruce.DateAdded
            )
OUTPUT deleted.*, $action, inserted.*;

最后的OUTPUT语句显示了更新/插入/删除的内容,如果您希望记录发生的事情,您可以在之后使用 into 语句将其转储到表中。我还添加了日期字段,以便您可以看到何时输入、更新或删除用户。我建议不要删除行,而只是用删除日期标记它,以便在用户离开公司后从AD中删除历史用户时不会失去它们。

希望对你有帮助。

我知道这被标记为c#,但在VB中(如果需要,使用语言转换器,telerik非常好),我会这样做:

Dim dEntry As New DirectoryServices.DirectoryEntry("LDAPAddress", "USERNAME", "PASSWORD")
Dim dSearcher As New DirectoryServices.DirectorySearcher
'You may need to tweek this next line according to your AD forest'
dSearcher = New DirectoryServices.DirectorySearcher("(&(objectCategory=Person)(objectClass=user))")
dSearcher.SearchRoot = dEntry
dSearcher.SizeLimit = 1000000
Dim srColl As DirectoryServices.SearchResultCollection = dSearcher.FindAll()
For Each result As DirectoryServices.SearchResult In srColl
    Dim resultProperties As DirectoryServices.ResultPropertyCollection = result.Properties
    'Use watch to get the details you need from AD in the resultProperties object'
     'FOR AD GUID'
     Dim ADGuid As String = ""
     If resultProperties.Contains("objectguid") Then
         Dim _byte As Byte() = resultProperties("objectguid").Item(0)
         ADGuid = New Guid(_byte).ToString
     End If
Next

LDAPAddress看起来像"LDAP://OU=WWWW,OU=XXXX,DC=YYYY,DC=ZZZZ"

最新更新