我的应用程序中有LDAP身份验证。如何从LDAP存储中获取“givenname”或“surname”等字段并将它们存储在SQL数据库中?
此外,仅当LDAP“uid”与本地数据库中存储的“uid”匹配时,是否也可以授权用户?
任何帮助将不胜感激。感谢。
答案 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'
然后,您可以使用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语句必须是一个没有换行符的连续行,否则会引发错误。
如果你的域名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)。
您还可以使用 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'的详细信息。
当我使用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"