首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Active中保存用户列表时调用错误

在Active中保存用户列表时调用错误
EN

Stack Overflow用户
提问于 2013-06-10 08:15:55
回答 2查看 1.7K关注 0票数 0

我在使用ASP.Net MVC 4应用程序(Framework4.5)从csv文件中保存活跃目录中的用户时遇到了问题。问题是,正确保存了第一个用户,但第二个用户返回了这个错误:

'/ADManagementStudio‘应用程序中的服务器错误。 访问被拒绝。(HRESULT例外: 0x80070005 (E_ACCESSDENIED)) 描述:在执行当前web请求时发生了未处理的异常。请查看堆栈跟踪以获得有关错误的更多信息,以及它起源于代码的位置。 异常详细信息: System.UnauthorizedAccessException:访问被拒绝。(HRESULT例外: 0x80070005 (E_ACCESSDENIED)) ASP.NET未被授权访问请求的资源。..。 源错误: 在执行当前web请求期间生成一个未处理的异常。有关异常的起源和位置的信息可以使用下面的异常堆栈跟踪来标识。 堆栈跟踪: UnauthorizedAccessException:访问被拒绝。(HRESULT例外: 0x80070005 (E_ACCESSDENIED)) System.DirectoryServices.DirectoryEntry.Invoke(String methodName,Object[] args) +630438 ADManagementStudio.Web.Controllers.UsersController.AddUsers(HttpPostedFileBase文件) +1437 ADManagementStudio.Web.Controllers.UsersController.CSV(HttpPostedFileBase文件) +23 lambda_method(闭包,ControllerBase,Object[] ) +127 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary2 parameters) +248 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2参数) +39 System.Web.Mvc.Async.<>c_DisplayClass39.b_33() +120 System.Web.Mvc.Async.<>c_DisplayClass4f.b_49() +452 System.Web.Mvc.Async.<>c_DisplayClass37.b_36(IAsyncResult asyncResult) +15 System.Web.Mvc.Async.<>c_DisplayClass2a.b_20() +31 System.Web.Mvc.Async.<>c_DisplayClass25.b_22(IAsyncResult asyncResult) +230 System.Web.Mvc.<>c_DisplayClass1d.b_18(IAsyncResult asyncResult) +28 System.Web.Mvc.Async.<>c_DisplayClass4.b_3(IAsyncResult ar) +15 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53 System.Web.Mvc.Async.<>c_DisplayClass4.b_3(IAsyncResult ar) +15 System.Web.Mvc.<>c_DisplayClass8.b_3(IAsyncResult asyncResult) +42 System.Web.Mvc.Async.<>c_DisplayClass4.b_3(IAsyncResult ar) +15 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,布尔& completedSynchronously) +288

我在web.config中使用了模拟,但我觉得很有趣的是,只有第一个用户被保存,而其他用户没有保存,有什么区别吗?(或许我只是因为我的糟糕经验而忽略了它)

在这里,函数的代码:

代码语言:javascript
运行
复制
private string AddUsers(HttpPostedFileBase file)
    {
        string tempFileName = string.Format("{0}_{1}", Guid.NewGuid(), Path.GetFileName(file.FileName));
        string filePath = Path.Combine(Server.MapPath("~/AD_App_Data/temp"), tempFileName);

        file.SaveAs(filePath);

        FileInfo tempFileInfo = new FileInfo(filePath);
        List<string[]> tempFileData = new List<string[]>();
        List<string> lines = new List<string>();

        using (StreamReader reader = new StreamReader(tempFileInfo.FullName, true))
        {
            string line = string.Empty;

            while ((line = reader.ReadLine()) != null)
            {
                string[] splitter = line.Split(';');

                lines.Add(line);
                tempFileData.Add(splitter);
            }
        }

        tempFileInfo.Delete();

        if ((tempFileData[0][0].ToLower() != "samaccountname") ||
            (tempFileData[0][1].ToLower() != "displayname"))
        {
            return "Error! sAMAccountName or displayName fields not found!";
        }

        try
        {
            string LDAPContextPath = string.Format(
                "LDAP://{0}/{1}",
                ActiveDirectoryManage.GetServerName(),
                ActiveDirectoryManage.GetLDAPUserPath());
            List<string> newUsersPassword = new List<string>();
            using (DirectoryEntry context = new DirectoryEntry(LDAPContextPath, "Administrator", "abcd,1234"))
            {
                foreach (string[] data in tempFileData.Skip(1))
                {
                    using (DirectoryEntry userEntry = context.Children.Add(string.Format("CN={0}", data[1]), "user"))
                    {
                        userEntry.Properties["sAMAccountName"].Value = data[0];
                        userEntry.CommitChanges();

                        for (int i = 1; i < data.Length; i++)
                        {
                            int number;

                            if (int.TryParse(data[i], out number))
                            {
                                userEntry.Properties[tempFileData[0][i]].Value = number;
                            }
                            else
                            {
                                userEntry.Properties[tempFileData[0][i]].Value = data[i];
                            }

                            userEntry.CommitChanges();
                        }

                        string newPassword = Membership.GeneratePassword(12, 0);

                        userEntry.Invoke("SetPassword", newPassword);
                        userEntry.CommitChanges();
                        newUsersPassword.Add(newPassword);
                        userEntry.Properties["userAccountControl"].Value = 512;
                        userEntry.CommitChanges();
                    }
                }

                Thread.Sleep(1000);
            }

            string timestamp = string.Format(
                "{0}{1}{2}-{3}{4}{5}",
                DateTime.Today.Hour, DateTime.Today.Minute, DateTime.Today.Second,
                DateTime.Today.Day, DateTime.Today.Month, DateTime.Today.Year);
            string doneFileName = string.Format("{0}_{1}.csv", file.FileName, timestamp);
            string donePath = Path.Combine(Server.MapPath("~/AD_App_Data/done"), doneFileName);

            using (StreamWriter writer = new StreamWriter(donePath))
            {
                writer.WriteLine(AppendPassword(lines[0], "password"));

                for (int i = 1; i < lines.Count; i++)
                {
                    writer.WriteLine(AppendPassword(lines[i], newUsersPassword[i - 1]));
                }
            }

            return doneFileName;
        }
        catch (DirectoryServicesCOMException ex)
        {
            return "Error! Exception! " + ex.Message;
        }
    }

谢谢你的忠告

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-10 18:57:22

好了,伙计们,我终于成功了!由于某些原因,现在我忽略了,我用编程的方式模拟了一个拥有足够权限的用户,在每次迭代中管理AD。

这里,描述如何以编程方式实现服务器端模拟的页面上的链接

下面我是如何使用它的:

代码语言:javascript
运行
复制
private string AddUsers(HttpPostedFileBase file)
    {
        string tempFileName = string.Format("{0}_{1}", Guid.NewGuid(), Path.GetFileName(file.FileName));
        string filePath = Path.Combine(Server.MapPath("~/AD_App_Data/temp"), tempFileName);

        file.SaveAs(filePath);

        FileInfo tempFileInfo = new FileInfo(filePath);
        List<string[]> tempFileData = new List<string[]>();
        List<string> lines = new List<string>();

        using (StreamReader reader = new StreamReader(tempFileInfo.FullName, true))
        {
            string line = string.Empty;

            while ((line = reader.ReadLine()) != null)
            {
                string[] splitter = line.Split(';');

                lines.Add(line);
                tempFileData.Add(splitter);
            }
        }

        tempFileInfo.Delete();

        if ((tempFileData[0][0].ToLower() != "samaccountname") ||
            (tempFileData[0][1].ToLower() != "displayname"))
        {
            return "Error! sAMAccountName or displayName fields not found!";
        }

        List<string> users = new List<string>();

        try
        {
            string LDAPContextPath = string.Format(
                "LDAP://{0}/{1}",
                ActiveDirectoryManage.GetServerName(),
                ActiveDirectoryManage.GetLDAPUserPath());
            List<string> newUsersPassword = new List<string>();

            foreach (string[] data in tempFileData.Skip(1))
            {
                if (impersonateValidUser("Administrator", ActiveDirectoryManage.GetDomainName(), "abcd,1234"))
                {
                    using (DirectoryEntry context = new DirectoryEntry(LDAPContextPath, "Administrator", "abcd,1234"))
                    {
                        users.Add(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
                        using (DirectoryEntry userEntry = context.Children.Add(string.Format("CN={0}", data[1]), "user"))
                        {
                            userEntry.Properties["sAMAccountName"].Value = data[0];
                            userEntry.CommitChanges();

                            for (int i = 1; i < data.Length; i++)
                            {
                                int number;

                                if (int.TryParse(data[i], out number))
                                {
                                    userEntry.Properties[tempFileData[0][i]].Value = number;
                                }
                                else
                                {
                                    userEntry.Properties[tempFileData[0][i]].Value = data[i];
                                }

                                userEntry.CommitChanges();
                            }

                            string newPassword = Membership.GeneratePassword(12, 0);

                            userEntry.Invoke("SetPassword", newPassword);
                            userEntry.CommitChanges();
                            newUsersPassword.Add(newPassword);
                            userEntry.Properties["userAccountControl"].Value = 512;
                            userEntry.CommitChanges();
                        }
                    }
                    undoImpersonation();
                }
                else
                {
                    return "Error! Impersonation Failed";
                }
            }


            string timestamp = string.Format(
                "{0}{1}{2}-{3}{4}{5}",
                DateTime.Today.Hour, DateTime.Today.Minute, DateTime.Today.Second,
                DateTime.Today.Day, DateTime.Today.Month, DateTime.Today.Year);
            string doneFileName = string.Format("{0}_{1}.csv", file.FileName, timestamp);
            string donePath = Path.Combine(Server.MapPath("~/AD_App_Data/done"), doneFileName);

            using (StreamWriter writer = new StreamWriter(donePath))
            {
                writer.WriteLine(AppendPassword(lines[0], "password"));

                for (int i = 1; i < lines.Count; i++)
                {
                    writer.WriteLine(AppendPassword(lines[i], newUsersPassword[i - 1]));
                }
            }

            return doneFileName;
        }
        catch (Exception ex)
        {
            string error = "Error! Exception! " + ex.Message + "\n\n";

            foreach (string s in users)
            {
                error = error + s + "\n\n";
            }

            return error;
        }
    }

我希望这篇文章能有所帮助!

票数 0
EN

Stack Overflow用户

发布于 2013-06-10 09:45:59

如果使用的是模拟,则需要确保模拟用户具有修改/创建活动目录中的对象的足够权限。如果模拟用户不是域管理员或没有自定义权限集,则几乎永远不会发生这种情况。

我建议您放弃模拟,或者将应用程序池作为一个在活动目录中具有有限权限的域帐户运行(至少在这里考虑--特权,只给它执行其工作所需的权限),或者使用与建议的应用程序池帐户具有相同限制的域帐户在代码中手动创建模拟上下文。

中有几个链接,所以答案可能会帮助您在代码中模拟另一个用户。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17019542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档