我正在尝试使用.Net中的目录服务运行简单的LDAP查询。
DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com");
directoryEntry.AuthenticationType = AuthenticationTypes.Secure;
DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
directorySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", username);
var result = directorySearcher.FindOne();
var resultDirectoryEntry = result.GetDirectoryEntry();
return resultDirectoryEntry.Properties["msRTCSIP-PrimaryUserAddress"].Value.ToString();
我得到以下例外:
System.Runtime.InteropServices.COMException (0x80005000): Unknown error (0x80005000)
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()
作为控制台应用中的代码段,这是有效的。但是当我将它作为WCF服务的一部分运行(在相同的凭据下运行)时,它会抛出上述异常。
有什么建议吗?
由于
答案 0 :(得分:86)
我一次又一次地拥有同样的东西,似乎没有任何帮助。
将路径从ldap://
更改为LDAP://
就可以了。
答案 1 :(得分:31)
这是一个许可问题。
当您运行控制台应用时,该应用会使用您的凭据运行,例如作为“你”。
WCF服务在哪里运行?在IIS?最有可能的是,它在一个单独的帐户下运行,该帐户无权查询Active Directory。
您可以尝试让WCF模拟工作正常,以便传递您自己的凭据,或者您可以在创建DirectoryEntry时指定用户名/密码:
DirectoryEntry directoryEntry =
new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com",
userName, password);
好的,所以它可能不是凭证(在我看到的80%以上的案例中通常就是这种情况)。
如何更改代码呢?
DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
directorySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", username);
directorySearcher.PropertiesToLoad.Add("msRTCSIP-PrimaryUserAddress");
var result = directorySearcher.FindOne();
if(result != null)
{
if(result.Properties["msRTCSIP-PrimaryUserAddress"] != null)
{
var resultValue = result.Properties["msRTCSIP-PrimaryUserAddress"][0];
}
}
我的想法是:为什么不直接告诉DirectorySearcher
你感兴趣的属性是什么?然后你不需要再做一个额外的步骤来从搜索结果中获取完整的DirectoryEntry
(应该更快),并且因为你告诉目录搜索者找到那个属性,它肯定会被加载到搜索结果 - 所以除非它是null(没有设置值),否则你应该能够轻松地检索它。
马克
答案 2 :(得分:16)
在Ektron的上下文中,通过在Windows中安装“IIS6元数据库兼容性”功能解决了此问题:
检查IIS6 Metabase的“Windows功能”或“角色服务” 兼容性,如果缺少则添加:
答案 3 :(得分:10)
我有同样的错误 - 在我的情况下,它是路径参数中的额外斜杠,它产生了不同。
BAD:
DirectoryEntry directoryEntry =
new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com/",
userName, password);
GOOD:
DirectoryEntry directoryEntry =
new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com",
userName, password);
答案 4 :(得分:7)
我也有这个错误,对我来说,这是一个名为“文件/文件夹访问组”的正斜杠的OU。
这forum thread指出了正确的方向。最后,在使用前在每个路径值上调用.Replace("/","\\/")
解决了我的问题。
答案 5 :(得分:5)
在IIS托管网站上,尝试回收应用池。它解决了我的问题。 感谢
答案 6 :(得分:3)
仅供参考,我遇到了同样的错误并使用了正确的凭据但我的LDAP网址错误:(
我收到完全相同的错误消息和代码
答案 7 :(得分:3)
在我居住的公司的生产系统中遇到了这个问题...在IP更改后,使LDAP绑定停止工作的网页。
解决方案...... ...我安装了基本身份验证以执行此处指示的问题排查:https://support.microsoft.com/en-us/kb/329986
在那之后,事情开始发挥作用。即使在我测试的页面中重新禁用基本身份验证之后,所有其他页面也开始使用Windows身份验证。
此致 Acácio
答案 8 :(得分:1)
如果物理机内存不足,则可能发生此错误。 在我的情况下,我在IIS上托管一个试图访问AD的站点,但是服务器内存不足。
答案 9 :(得分:0)
如果在DirectoryEntry.Patch中符号“LDAP //:”后面没有任何内容,则会发生同样的错误。有必要在directorySearcher.FindOne()之前检查directoryEntry.Path。除非明确指定域,否则不需要“LDAP://”。
private void GetUser(string userName, string domainName)
{
DirectoryEntry dirEntry = new DirectoryEntry();
if (domainName.Length > 0)
{
dirEntry.Path = "LDAP://" + domainName;
}
DirectorySearcher dirSearcher = new DirectorySearcher(dirEntry);
dirSearcher.SearchScope = SearchScope.Subtree;
dirSearcher.Filter = string.Format("(&(objectClass=user)(|(cn={0})(sn={0}*)(givenName={0})(sAMAccountName={0}*)))", userName);
var searchResults = dirSearcher.FindAll();
//var searchResults = dirSearcher.FindOne();
if (searchResults.Count == 0)
{
MessageBox.Show("User not found");
}
else
{
foreach (SearchResult sr in searchResults)
{
var de = sr.GetDirectoryEntry();
string user = de.Properties["SAMAccountName"][0].ToString();
MessageBox.Show(user);
}
}
}
答案 10 :(得分:0)
在我的类似问题上花了一天时间,但所有这些答案都没有用。
在我的情况下,我没有在IIS设置中启用Windows身份验证...
答案 11 :(得分:0)
我必须从此更改代码:
DirectoryEntry entry = new DirectoryEntry(path, ldapUser, ldapPassword);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = entry;
searcher.SearchScope = SearchScope.Subtree;
对此:
DirectoryEntry entry = new DirectoryEntry(path, ldapUser, ldapPassword);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.OneLevel;
SearchResult searchResult = searcher.FindOne();
答案 12 :(得分:0)
查询forrest的另一个域的条目时遇到此错误,并且该条目具有另一个域的一些自定义属性。
要解决此错误,我只需要在URL LDAP中指定服务器:
错误= LDAP://CN=MyObj,DC=DOMAIN,DC=COM
的路径
没有错误的路径:LDAP://domain.com:389/CN=MyObj,DC=Domain,DC=COM