windows 无法查询 AD(获取 DirectoryServicesCOMException)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3469883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't query AD (get a DirectoryServicesCOMException)
提问by KevinDeus
I'm attempting to query AD in an ASP.Net (4.0) application that is running on Windows Server 2008 R2 (IIS7 installed). (It also fails when running as a 2.0 application as well)
我正在尝试在 Windows Server 2008 R2(安装了 IIS7)上运行的 ASP.Net (4.0) 应用程序中查询 AD。(当作为 2.0 应用程序运行时它也会失败)
This is nothing new for me, as I've done this many times before. I wrote a small ASP.Net program that runs fine on my own machine (Windows XP with IIS6), but fails when run on the 2008 box.
这对我来说并不新鲜,因为我以前做过很多次。我写了一个小的 ASP.Net 程序,它在我自己的机器上运行良好(带有 IIS6 的 Windows XP),但在 2008 机器上运行时失败。
(The result is that you see a list of groups the user is a member of in a textbox)
(结果是您在文本框中看到用户所属的组列表)
(on button_click)
var userName = txtUserName.Text;
if (userName.Trim().Length == 0)
{
txtResults.Text = "-- MISSING USER NAME --";
return;
}
var entry = new DirectoryEntry("LDAP://blah.blah/DC=blah,DC=blah",
"cn=acct, dc=blah, dc=blah",
"pass");
var search = new DirectorySearcher(entry);
search.Filter = "(SAMAccountName=" + userName + ")";
search.PropertiesToLoad.Add("memberOf");
var groupsList = new StringBuilder();
var result = search.FindOne();
if (result != null)
{
int groupCount = result.Properties["memberOf"].Count;
for (int counter = 0; counter < groupCount; counter++)
{
groupsList.Append((string)result.Properties["memberOf"][counter]);
groupsList.Append("\r\n");
}
}
txtResults.Text = groupsList.ToString();
When I run this code I get the following error on search.FindOne():
当我运行此代码时,在 search.FindOne() 上出现以下错误:
System.DirectoryServices.DirectoryServicesCOMException (0x8007203B): A local error has occurred.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FindOne()
at WebApplication1._Default.btnSearch_Click(Object sender, EventArgs e)
We've done a lot of research with this and twiddled every IIS7 setting we can think of, but no go so far. Any clues?
我们对此进行了大量研究,并对我们能想到的每个 IIS7 设置进行了调整,但还没有走这么远。有什么线索吗?
采纳答案by John
Change the username parameter from "cn=xxx, dc=yyy, dc=zzz" to "Domain\Username"
将用户名参数从“cn=xxx,dc=yyy,dc=zzz”改为“Domain\Username”
回答by Avada Kedavra
I see that the question is rather old, but after struggling with this I thought to mention that it is indeed possible to use the LDAP-style of the username (in opposite to the DNS style). This works well for me:
我看到这个问题已经很老了,但是在为此苦苦挣扎之后,我想提到确实可以使用用户名的 LDAP 样式(与 DNS 样式相反)。这对我很有效:
string connString = "LDAP://MyDomain/CN=blah,DC=blah,DC=blah";
string username = "CN=MyAdmin,CN=Users,CN=blah,DC=blah,DC=blah";
string password = "myLittleSecret";
DirectoryEntry root = new DirectoryEntry(
connString,
username,
password,
AuthenticationTypes.None);
Where MyAdmin
is a member in the Administrators
role.
角色中MyAdmin
的成员在哪里Administrators
。
One little thing that took me a while to find is the AuthenticationTypes.None
parameter that is needed if you do not want to communicate over SSL. Surely, you want to do this in production, but for development purposes it may be OK to skip the encryption.
我花了一段时间才找到的一件小事AuthenticationTypes.None
是如果您不想通过 SSL 进行通信所需的参数。当然,您想在生产中执行此操作,但出于开发目的,跳过加密可能没问题。
Environment: Windows 7
环境:Windows 7
回答by nbi
I was also getting this exception when tried to query the active directory:
尝试查询活动目录时,我也遇到此异常:
SearchResult result = srch.FindOne();
To resolve this, just put the above code inside Security.RunWithElevatedPrivileges()
.
要解决这个问题,只需将上面的代码放在Security.RunWithElevatedPrivileges()
.
Final Solution:
最终解决方案:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
result = srch.FindOne();
});
回答by Jeff Siver
You can also change the IIS Application Pool to run a domain account with the query priveleges you are searching for.
您还可以更改 IIS 应用程序池以运行具有您正在搜索的查询权限的域帐户。
I have a few other comments as well:
我还有其他一些评论:
- Make sure the first entry for the DirectoryEntry constructor includes the container for the users as well. This should help the DirectorySearcher to work more reliably.
- I believe the second parameter in the DirectoryEntry constructor should be the user name, not the AD query path.
- You should set the AuthenticationType property as well. With Server 2008, by default, this needs to be set to AuthenticationTypes.Secure | AuthenticationTypes.ServerBind | AuthenticationTypes.Sealing. I'd guess that 2008R2 has a simliar requirement.
- 确保 DirectoryEntry 构造函数的第一个条目也包含用户的容器。这应该有助于 DirectorySearcher 更可靠地工作。
- 我相信 DirectoryEntry 构造函数中的第二个参数应该是用户名,而不是 AD 查询路径。
- 您还应该设置 AuthenticationType 属性。对于 Server 2008,默认情况下,这需要设置为 AuthenticationTypes.Secure | AuthenticationTypes.ServerBind | AuthenticationTypes.Sealing。我猜想 2008R2 有类似的要求。