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

时间:2013-04-29 13:26:36

标签: c# sql ldap

我的应用程序中有LDAP身份验证。如何从LDAP存储中获取“givenname”或“surname”等字段并将它们存储在SQL数据库中?

此外,仅当LDAP“uid”与本地数据库中存储的“uid”匹配时,是否也可以授权用户?

任何帮助将不胜感激。感谢。

2 个答案:

答案 0 :(得分:1)

可以使用SQL Server本身,您可以设置Linked 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'DOMAIN\login',
    @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,那么构建''LDAP://''部分.domain.net 然后它是''LDAP:// DC = corp,DC = domain,DC = net''或只是 domain.net 是的 '' LDAP:// DC =域,DC =净 ''

查找要选择的字段

如果您要在上面的select语句中使用all列运算符(*),您将获得 userClass 用户的所有可能字段,您可以执行相同操作对于等,要发现需要返回的字段,字段名称区分大小写。

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

过滤LDAP数据

您还可以使用 userAccountControl 字段(list of values)来检查帐户的状态,这是一个按位字段,您可以在OPENQUERY函数中进行按位检查使用 1.2.840.113556.1.4.804 LDAP_MATCHING_RULE_BIT_OR,使用上述语句的示例:

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中禁用,该语句就会返回用户'nouptime'的详细信息。

插入&amp;更新(升级)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中删除,则不会丢失历史用户。

希望有所帮助。

答案 1 :(得分:0)

我知道这被标记为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"