2011-12-20 129 views
0

如果我有以下的AD域路径:搜索全球域名在Active Directory中

AD路径:

  • LDAP://AAA.CORP.XX.COM
  • LDAP://BBB.CORP.XX.COM
  • LDAP://CCC.BBB.CORP.XX.COM
  • LDAP://DDD.CORP.XX.COM
  • LDAP://EEE.CORP.XX.COM
  • LDAP://FFF.CORP.XX.COM

我需要在上述结构域(如果存在)在它们中的一个或不搜索用户。

我当前的解决方案:

我通过以上并为每个域的所有结构域I检查用户是否存在或不与在域之一环绕它上面从6-7秒把剩下了不到1第二。

提出的解决方案,以提高性能:

  1. 尝试搜索用户在父域中,应该是LDAP://CORP.XX.COM所以这将节省而不是5次的搜索搜索的每个域的数量为1个搜索父域
  2. 尝试使用“全球目录” ==>我需要在这里GUID(教程,C#代码)

哪种方案更好地提高性能问题?

+0

你有什么代码..?你的连接是什么cn = dn = ect ...看起来像..你在创建一个DirectorySearcher对象吗?当搜索用户什么属性你打算搜索/检查..? SAMAccount ...等。 – MethodMan 2011-12-20 20:14:07

+0

DirectoryEntry de = new DirectoryEntry(); de.Path =“LDAP://AAA.CORP.XX。COM“;搜索过滤器格式=(&(objectClass =用户)(sAMAccountName = {0})) – 2011-12-20 20:46:20

+0

坚持让我看看我是否可以给你一些代码片段,你将能够遵循给我2分钟好吧公众字符串的GetName(字符串用户名)也将为你工作..无论如何,你喜欢我 – MethodMan 2011-12-20 20:47:46

回答

0

这里是我写的,并在多处使用看通的方法,看看你可以使用什么类..

using System; 
using System.Text; 
using System.Collections; 
using System.DirectoryServices; 
using System.Diagnostics; 
using System.Data.Common; 

namespace Vertex_VVIS.SourceCode 
{ 
    public class LdapAuthentication 
    { 
     private String _path; 
     private String _filterAttribute; 

     public LdapAuthentication(String path) 
     { 
      _path = path; 
     } 
public bool IsAuthenticated(String domain, String username, String pwd) 
     { 
      String domainAndUsername = domain + @"\" + username; 
      DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd); 

      try 
      { //Bind to the native AdsObject to force authentication.   
       // Object obj = entry.NativeObject; 

       DirectorySearcher search = new DirectorySearcher(entry); 

       search.Filter = "(SAMAccountName=" + username + ")"; 
       search.PropertiesToLoad.Add("cn"); 
       SearchResult result = search.FindOne(); 

       if (null == result) 
       { 
        return false; 
       } 

       //Update the new path to the user in the directory. 
       _path = result.Path; 
       _filterAttribute = (String)result.Properties["cn"][0]; 
      } 
      catch (Exception ex) 
      { 
       throw new Exception("Error authenticating user. " + ex.Message); 
      } 

      return true; 
     } 

     public String GetName(string username) 
     { 

      String thename = null; 

      try 
      { 
       DirectoryEntry de = new DirectoryEntry(_path); 
       DirectorySearcher ds = new DirectorySearcher(de); 
       ds.Filter = String.Format("(SAMAccountName={0})", username); 
       ds.PropertiesToLoad.Add("displayName"); 
       SearchResult result = ds.FindOne(); 
       if (result.Properties["displayName"].Count > 0) 
       { 
        thename = result.Properties["displayName"][0].ToString(); 
       } 
       else 
       { 
        thename = "NA"; 
       } 
      } 
      catch (Exception ex) 
      { 
       throw new Exception("Error Getting Name. " + ex.Message); 
      } 

      return thename.ToString(); 
     } 

     public String GetEmailAddress(string username) 
     { 
      String theaddress = null; 
      try 
      { 
       DirectoryEntry de = new DirectoryEntry(_path); 
       DirectorySearcher ds = new DirectorySearcher(de); 
       ds.Filter = String.Format("(SAMAccountName={0})", username); 
       ds.PropertiesToLoad.Add("mail"); 
       SearchResult result = ds.FindOne(); 
       theaddress = result.Properties["mail"][0].ToString(); 
       de.Close(); 
      } 
      catch (Exception ex) 
      { 
       throw new Exception("Error Getting Email Address. " + ex.Message); 
      } 

      return theaddress.ToString(); 
     } 
     public String GetTitle(string username) 
     { 
      String thetitle = null; 
      try 
      { 
       DirectoryEntry de = new DirectoryEntry(_path); 
       DirectorySearcher ds = new DirectorySearcher(de); 
       ds.Filter = String.Format("(SAMAccountName={0})", username); 
       ds.PropertiesToLoad.Add("title"); 
       SearchResult result = ds.FindOne(); 
       result.GetDirectoryEntry(); 
       if (result.Properties["title"].Count > 0) 
       { 
        thetitle = result.Properties["title"][0].ToString(); 
       } 
       else 
       { 
        thetitle = "NA"; 
       } 
      } 
      catch (Exception ex) 
      { 
       throw new Exception("Error Getting the Title. " + ex.Message); 
      } 

      return thetitle.ToString(); 
     } 

     public String GetPhone(string username) 
     { 
      String thephone = null; 
      try 
      { 
       DirectoryEntry de = new DirectoryEntry(_path); 
       DirectorySearcher ds = new DirectorySearcher(de); 
       ds.Filter = String.Format("(SAMAccountName={0})", username); 
       ds.PropertiesToLoad.Add("mobile"); 
       SearchResult result = ds.FindOne(); 
       result.GetDirectoryEntry(); 
       if (result.Properties["mobile"].Count > 0) 
       { 
        thephone = result.Properties["mobile"][0].ToString(); 
       } 
       else 
       { 
        thephone = "NA"; 
       } 
      } 
      catch (Exception ex) 
      { 
       throw new Exception("Error Getting Phone Number. " + ex.Message); 
      } 

      return thephone.ToString(); 
     } 

     public String GetGroups() 
     { 
      DirectorySearcher search = new DirectorySearcher(_path); 
      search.Filter = "(cn=" + _filterAttribute + ")"; 
      search.PropertiesToLoad.Add("memberOf"); 
      StringBuilder groupNames = new StringBuilder(); 

      try 
      { 
       SearchResult result = search.FindOne(); 

       int propertyCount = result.Properties["memberOf"].Count; 

       String dn; 
       int equalsIndex, commaIndex; 

       for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++) 
       { 
        dn = (String)result.Properties["memberOf"][propertyCounter]; 

        equalsIndex = dn.IndexOf("=", 1); 
        commaIndex = dn.IndexOf(",", 1); 
        if (-1 == equalsIndex) 
        { 
         return null; 
        } 

        groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1)); 
        groupNames.Append("|"); 

       } 
      } 
      catch (Exception ex) 
      { 
       throw new Exception("Error obtaining group names. " + ex.Message); 
      } 
      return groupNames.ToString(); 
     } 

     public bool IsUserGroupMember(string strUserName, string strGroupString) 
     { 
      bool bMemberOf = false; 
      ResultPropertyValueCollection rpvcResult = null; 
      try 
      { 
       DirectoryEntry de = new DirectoryEntry(_path); 
       DirectorySearcher ds = new DirectorySearcher(de); 
       ds.Filter = String.Format("(SAMAccountName={0})", strUserName); 
       ds.PropertiesToLoad.Add("memberOf"); 
       SearchResult result = ds.FindOne(); 
       string propertyName = "memberOf"; 
       rpvcResult = result.Properties[propertyName]; 

       foreach (Object propertyValue in rpvcResult) 
       { 
        if (propertyValue.ToString().ToUpper() == strGroupString.ToUpper()) 
        { 
         bMemberOf = true; 
         break; 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       throw new Exception("Error Getting member of. " + ex.Message); 
      } 

      return bMemberOf; 

     } 
    } 
} 
+0

感谢DJ,我通过代码移动了它,但它似乎是基于域路径搜索用户。所以我仍然有同样的问题,我会搜索每个域,它是我的主要问题,我需要击中搜索1次而不是5次 - – 2011-12-20 22:07:38

2

如果您使用.NET 3.5或更新版本,你应该能够使用PrincipalSearcher和“查询通过例如”主要做你的搜索:

// create your domain context 
// here, you could also include a specific domain, if needed 
PrincipalContext ctx = new PrincipalContext(ContextType.Domain); 

// define a "query-by-example" principal - here, we search for a UserPrincipal 
UserPrincipal qbeUser = new UserPrincipal(ctx); 

// if you're looking for a particular user - you can limit the search by specifying 
// e.g. a SAMAccountName, a first name - whatever criteria you are looking for 
qbeUser.SamAccountName = "johndoe"; 

// create your principal searcher passing in the QBE principal  
PrincipalSearcher srch = new PrincipalSearcher(qbeUser); 

// find all matches 
foreach(var found in srch.FindAll()) 
{ 
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....   
} 

您可以在UserPrincipal指定任何属性,并使用这些作为“查询通过例如”为您PrincipalSearcher 。这比使用旧的DirectorySearcher方法容易得多。

如果您还没有 - 绝对看MSDN文章Managing Directory Security Principals in the .NET Framework 3.5这很好地说明如何使新功能的最佳使用System.DirectoryServices.AccountManagement

+0

感谢marc_s:我错过了确定父域名的一段代码(我猜想我的情况应该是:CORP.XX.COM)我应该在principalContext()中传递此名称吗? – 2011-12-20 21:42:10

+0

@ thabet084:我会尝试开始时不传递任何东西 - 只是为了查看你最终在哪里以及它首先搜索的位置。一旦启动并运行,然后开始播放各种LDAP路径作为起点。 – 2011-12-20 21:44:15

+0

好点Marc我完全忘了那个..我个人很喜欢使用我发布的内容,因为LDAP,AD和一个Java工具,我不得不查询一次,看起来很熟悉,现在我看到上下文哈哈我投你了 – MethodMan 2011-12-20 22:18:28