2

寻找使用 C# 通过 ADODB 连接到 Active Directory 的示例。

我的目标是能够运行查找以根据用户属性(用户 ID、电子邮件地址等)中的一个来验证用户在 Active Directory 中是否有效。

[想强调的是,使用 ADODB 是对此的要求,使用 DirectoryServices 不是有效的响应。]

我目前的方法不起作用(在 cmd.Execute 位例外):

object parms = null;
object recs = null;
ADODB.Connection conn = new ADODB.Connection();
ADODB.Command cmd = new ADODB.Command();
ADODB.Recordset rs = new ADODB.Recordset();

conn.Open("Provider=ADsDSOObject",obfsUser,obfsPass,0);

cmd.ActiveConnection = conn;
cmd.CommandText = "<LDAP://OU=obfsOU,DC=obfsDC,DC=corp,DC=Net>;;name;subtree";
rs = cmd.Execute(out recs, ref parms, 0);

我不确定我是否应该/在哪里提供服务器参考,我也不确定通过 ref 传递给 cmd.Execute 方法的参数应该是什么。没有大量用于通过 ADODB 从 C# 连接到 ActiveDirectory 的文档。

conn.State 返回 1,所以我相信我得到了一个活跃的连接。我认为问题在于传递给 cmd.Execute() 方法的参数。

4

3 回答 3

4

ScottCher 的答案有效,但有局限性,特别是您无法处理 1000 条记录结果限制。要做到这一点,唯一的方法是使用 Command 对象,相信我,这是一个雷区,因为 (a) C# 接口上没有好的文档,并且 (b) 令人难以置信的是没有完整的解决方案可以通过谷歌搜索在撰写本文时。

我花了最后几天在这方面,并且有一些工作我想回馈给我读过的所有资源,其中包括各种点点滴滴的拼图。

首先,正如在很多地方所指出的(遗憾的是,只有 VB 示例!),如果您不做一些特别的事情,那么所有 ADSI 查询都被限制为 1000 行结果。避免这种情况的关键是在 Command 对象上设置“页面大小”属性。我们将在几秒钟内完成,但首先我们需要使用命令使基本查询正常工作。如果你在这个线程中使用原始代码,你会在 cmd.Execute 上得到一个异常,抱怨参数不匹配。您会认为传入 null 作为 ref 对象就足够了,特别是因为 LDAP 语法(显然)没有参数。

我在两个地方找到了答案。首先,即使您没有明确指定参数,LDAP SQL 语法中的“:”似乎足以让 ADO 认为参数是必需的。奇怪,但似乎是真的。其次,指定“无参数”情况的正确方法是将值设置为Type.Missing,而不是null,如:

object parms = Type.Missing;

这是让 Execute 不抛出异常的关键。

现在有了一个有效的命令,我们现在可以解决 1000 行的限制。这是“简单地”通过在命令上指定“页面大小”属性,但从 C# 界面可以明显看出,它与 C# 属性不同。您需要将其放入 Properties 集合中,但这并没有公开一个很好的集合接口来执行此操作。经过反复试验,正确的语法是:

cmd.Properties["Page Size"].Value = 500;

I don't think it is important exactly what the page size is (still playing with that) but setting it to something is enough to tell ADSI to get all the results. And I sincerely hope this helps somebody.

于 2009-09-04T20:05:51.197 回答
2

这行得通。

希望这可以帮助其他有相同需求和问题的人。

[请注意缺少 ADODB.Command 对象,并且查询使用 SQL 格式而不是 ADSI 格式。]

object recs;

ADODB.Connection conn = new ADODB.Connection();
ADODB.Recordset rs = new ADODB.Recordset();

// You may need to provide user id and password instead of empty strings        
conn.Open("Provider=ADsDSOObject", "", "", 0);

// replace <> elements with your server name and OU/DC tree org
string server = "<enter your server name here>";
string start = "OU=<blah>,DC=<blah>,DC=<blah>,DC=<blah>";
string where = "objectClass = '*'";
string qry = string.Format("SELECT cn FROM 'LDAP://{0}/{1}' WHERE {2}", server, start, where);

rs = conn.Execute(qry, out recs, 0);

for (; !rs.EOF; rs.MoveNext())
{
    Console.WriteLine(rs.Fields["cn"].Value.ToString());
}
于 2009-07-17T00:22:57.523 回答
0

查看 Richard Mueller 在 Active Directory 上的网站 - 他专门有一个关于 ADO Search Tips for AD 的页面:

http://www.rlmueller.net/ADOSearchTips.htm

在他的网站上还有大量优秀的参考资料,例如具有所有 AD 属性及其特征的 Excel 表格。

强烈推荐!

马克

于 2009-07-17T05:49:46.543 回答