简体   繁体   English

如何使用C#和ADODB查询Active Directory?

[英]How do I query Active Directory using C# and ADODB?

Looking for an example of connecting via ADODB to Active Directory using C#. 寻找一个使用C#通过ADODB连接到Active Directory的示例。

My goal is to be able to run a lookup to verify that a user is valid in Active Directory based on one that of that users attributes (user id, email address, etc). 我的目标是能够基于该用户属性之一(用户ID,电子邮件地址等)运行查找以验证该用户在Active Directory中有效。

[Would like to stress that using ADODB is a requirement for this, using DirectoryServices is not a valid response.] [想强调指出,为此必须使用ADODB,使用DirectoryServices不是有效的响应。]

My current approach isn't working (exception at cmd.Execute bit): 我当前的方法不起作用(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);

I'm not sure if/where I'm supposed to provide the server reference and I'm not really sure what the parameteres passed into the cmd.Execute method by ref should be. 我不确定是否应该/在何处提供服务器引用,也不确定由ref传递给cmd.Execute方法的参数应该是什么。 Not a ton of documentation out there for connecting to ActiveDirectory from C# via ADODB. 没有大量的文档可用于通过ADODB从C#连接到ActiveDirectory。

conn.State is returning 1 so I believe I am getting an active connection. conn.State返回1,所以我相信我正在建立活动连接。 I think the problem is in the parameters passed to the cmd.Execute() method. 我认为问题出在传递给cmd.Execute()方法的参数中。

The answer by ScottCher works but it has limitations, notably that you cannot deal with the 1000 record result limit. ScottCher的答案有效,但它有局限性,尤其是您不能处理1000条记录结果的限制。 To do that, the only way is to use a Command object, and believe me, that is a minefield because there is (a) no good documentation on the C# interfaces, and (b) there is incredibly no full solution that can be Googled as of this writing. 为此, 唯一的方法是使用Command对象,并相信我,这是一个雷区,因为(a)C#接口上没有好的文档,并且(b)令人难以置信的是,没有可以谷歌搜索的完整解决方案在撰写本文时。

I have spent the last bunch of days on this, and have something working that I would like to give back to all the sources I have read with various bits and pieces to the puzzle. 我花了最后一整天的时间,并做了一些工作,我想将我阅读过的所有资料都以各种点滴的方式归还给大家。

First, as noted in a ton of places (sadly with VB examples only!), if you don't do something special then all ADSI queries are limited to 1000 rows of results. 首先,正如在很多地方提到的那样(仅使用VB示例!),如果您不做特别的事情,那么所有ADSI查询都限于1000行结果。 The key to avoiding this is to set the "Page Size" property on the Command object. 避免这种情况的关键是在Command对象上设置“页面大小”属性。 We'll get to that in a sec, but first we need to get the basic query working using a Command. 我们将在几秒钟内解决这个问题,但是首先我们需要使用Command来使基本查询正常工作。 If you use the original code in this thread, you will get an exception on cmd.Execute complaining about parameters mismatching. 如果您在此线程中使用原始代码,则会在cmd上收到异常。执行时会抱怨参数不匹配。 You would think that passing in null as the ref object would suffice, especially since the LDAP syntax does not (apparently) have parameters. 您可能会认为,将NULL作为ref对象传递就足够了,特别是因为LDAP语法(显然)没有参数。

I found the answer to this in two places. 我在两个地方找到了答案。 First, even though you are not explicitly specifying parameters, it would seem that the ":" in the LDAP SQL syntax is enough to make ADO think that parameters are required. 首先,即使您没有明确指定参数,LDAP SQL语法中的“:”似乎也足以使ADO认为需要参数。 Odd, but seemingly true. 奇怪,但看似真实。 Second, the CORRECT way to specify the "no parameters" case is to set the value to Type.Missing, not null, as in: 其次,指定“无参数”大小写的正确方法是将值设置为Type.Missing,而不是null,如下所示:

object parms = Type.Missing;

This was key to getting Execute to not throw an exception. 这是使Execute不引发异常的关键。

Now with a working Command we can now address the 1000 row limit. 现在使用有效的命令,我们现在可以解决1000行的限制。 This is "simply" by specifying the "Page Size" property on the Command but, as it obvious from the C# interface, it is not the same as a C# property. 通过在Command上指定“页面大小”属性,这是“简单”的操作,但是,从C#接口可以明显看出,它与C#属性不同。 You need to put it into the Properties collection, but this does not expose a nice collection interface to do that with. 您需要将其放入Properties集合中,但这并没有提供一个很好的集合接口来完成此任务。 After some trial and error, the correct syntax is: 经过反复试验,正确的语法是:

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. 我认为页面大小到底是什么(仍然在玩)并不重要,但是将其设置为足以告诉ADSI获得所有结果的大小。 And I sincerely hope this helps somebody. 我衷心希望这对某人有帮助。

This works. 这可行。

Hope this helps someone else having the same need and problems I had. 希望这可以帮助其他有我同样需求和问题的人。

[Note the lack of an ADODB.Command object and the use of SQL format for the query instead of ADSI format.] [请注意缺少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());
}

Check out Richard Mueller's web site on Active Directory - he specifically has a page on ADO Search Tips for AD: 在Active Directory上查看Richard Mueller的网站-他专门在ADO的AD搜索技巧页面上找到了一个页面:

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

There's also a slew of excellent reference material on his web site, like Excel sheets with all the AD properties and their characteristics. 他的网站上还有许多出色的参考资料,例如具有所有AD属性及其特征的Excel表。

Highly recommended! 强烈推荐!

Marc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM