【问题标题】:How to programmatically update and delete LDAP users from SQL?如何以编程方式从 SQL 中更新和删除 LDAP 用户?
【发布时间】:2011-12-03 02:09:13
【问题描述】:

所以我希望获取一些 ldap 值,并将它们插入到加密的数据库中。我已经插入工作,但我需要检查用户是否仍然是组的一部分,如果没有从数据库中删除它们,如果添加了新用户,它会插入它们而不是插入现有用户。你能给我一些关于最佳实践的指导吗?我不想截断表格并重新插入所有内容。

        try
        {
            /* Connection to Active Directory */
            DirectoryEntry deBase = new DirectoryEntry("LDAP://" + txtLDAP.Text + ":" + txtLDapPort.Text + "/" + txtBadeDN.Text, txtUsername.Text, txtPassword.Text, AuthenticationTypes.Secure);

            /* Directory Search*/
            DirectorySearcher dsLookForGrp = new DirectorySearcher(deBase);
            dsLookForGrp.Filter = String.Format("(cn={0})", txtGroup.Text);
            dsLookForGrp.SearchScope = SearchScope.Subtree;
            dsLookForGrp.PropertiesToLoad.Add("distinguishedName");
            SearchResult srcGrp = dsLookForGrp.FindOne();

            /* Directory Search
             */
            DirectorySearcher dsLookForUsers = new DirectorySearcher(deBase);
            dsLookForUsers.Filter = String.Format("(&(objectCategory=person)(memberOf={0}))", srcGrp.Properties["distinguishedName"][0]);
            dsLookForUsers.SearchScope = SearchScope.Subtree;
            dsLookForUsers.PropertiesToLoad.Add("objectSid");
            dsLookForUsers.PropertiesToLoad.Add("sAMAccountName");
            SearchResultCollection srcLstUsers = dsLookForUsers.FindAll();

            StringBuilder sbUsers = new StringBuilder();

            foreach (SearchResult sruser in srcLstUsers)
            {
                SecurityIdentifier sid = new SecurityIdentifier((byte[])sruser.Properties["objectSid"][0], 0);
                string ConnString = "ConnectionString Removed";
                string SqlString = "spInsertADAuthorization";
                using (OleDbConnection conn = new OleDbConnection(ConnString))
                {
                    using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("AD_Account", SpartaCrypto.SpartaEncryptAES(sruser.Properties["sAMAccountName"][0].ToString(), "thisisasharedsecret"));
                        cmd.Parameters.AddWithValue("AD_SID", SpartaCrypto.SpartaEncryptAES(sid.ToString(), "thisisasharedsecret"));
                        cmd.Parameters.AddWithValue("AD_EmailAddress", "user@host.com");
                        cmd.Parameters.AddWithValue("DateImported", DateTime.Now.ToString());
                        cmd.Parameters.AddWithValue("Active", 1);
                        conn.Open();
                        cmd.ExecuteNonQuery();
                        conn.Close();
                    }
                }
                lblResults.Text = srcLstUsers.Count + " Users granted access.";
            }
        }

        catch (Exception ex)
        {
            if (ex.Message.Contains("Logon failure"))
            {
                lblResults.Text = "Logon Failure.  Check your username or password.";
            }

            if (ex.Message.Contains("The server is not operational"))
            {
                lblResults.Text = "LDAP Error.  Check your hostname or port.";
            }
            if (ex.Message.Contains("Object reference not set to an instance of an object"))
            {
                lblResults.Text = "LDAP Error.  Check your hostname, port, or group name and try again.";
            }


        }

【问题讨论】:

    标签: c# c#-4.0 active-directory


    【解决方案1】:

    由于您使用的是 .NET 3.5 及更高版本,因此您应该查看 System.DirectoryServices.AccountManagement (S.DS.AM) 命名空间。在此处阅读所有相关信息:

    您可以使用PrincipalSearcher 和“示例查询”主体进行搜索:

    // create your domain context
    PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
    
    // define a "query-by-example" principal - here, we search for a UserPrincipal 
    // and with the first name (GivenName) of "Bruce"
    UserPrincipal qbeUser = new UserPrincipal(ctx);
    qbeUser.GivenName = "Bruce";
    
    // 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.....          
    }
    

    对于使用单个主体,编程接口也更好:

    // find a user
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
    
    if(user != null)
    {
       // do something here... you can access most of the commonly used properties easily
       user.GivenName = "....";
       user.Surname = "......";
       user.SamAccountName = ".....";
    }
    
    // find the group in question
    GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
    
    // if found....
    if (group != null)
    {
       // iterate over members
       foreach (Principal p in group.GetMembers())
       {
          Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
          // do whatever you need to do to those members
       }
    }
    

    新的 S.DS.AM 使得在 AD 中与用户和组一起玩真的更容易

    【讨论】:

    • 我会调查的,谢谢。但是我试图从中得到的想法是如何管理插入刚刚加入组的用户而不是重新插入我们已经在数据库中拥有的用户。同时删除数据库中但不再属于该组的用户。
    猜你喜欢
    • 2012-02-29
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多