0

ASP.Net MVC 4 アプリケーション (フレームワーク 4.5) を使用して、csv ファイルから Active Directory にユーザーを保存する際に問題があります。問題は、最初のユーザーが正しく保存されていることですが、2 番目のユーザーは次のエラーを返します。

「/ADManagementStudio」アプリケーションでサーバー エラーが発生しました。

アクセスが拒否されました。(HRESULT からの例外: 0x80070005 (E_ACCESSDENIED))

説明: 現在の Web 要求の実行中に未処理の例外が発生しました。エラーの詳細とコード内のどこでエラーが発生したかについては、スタック トレースを確認してください。

例外の詳細: System.UnauthorizedAccessException: アクセスが拒否されました。(HRESULT からの例外: 0x80070005 (E_ACCESSDENIED))

ASP.NET は、要求されたリソースへのアクセスを許可されていません。[...]

[...]

ソース エラー:

現在の Web 要求の実行中に未処理の例外が生成されました。例外の発生元と場所に関する情報は、以下の例外スタック トレースを使用して特定できます。

スタックトレース:

[UnauthorizedAccessException: アクセスが拒否されました。(HRESULT からの例外: 0x80070005 (E_ACCESSDENIED))]

[TargetInvocationException: 呼び出しのターゲットによって例外がスローされ
まし

。 Web.Controllers.UsersController.CSV(HttpPostedFileBase ファイル) +23 lambda_method(Closure , ControllerBase , Object[] ) +127 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary 2 パラメータ) +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.b2 parameters) +248
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary

_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, Boolean& completedSynchronously) +288

私は web.config で偽装を使用していますが、最初のユーザーだけが保存され、他のユーザーは保存されないのはおかしいと思います。他のユーザーと何が違うのでしょうか? (または、経験が乏しいために無視するだけかもしれません)

関数のコードは次のとおりです。

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;
        }
    }

アドバイスありがとう

4

2 に答える 2

0

偽装を使用している場合は、偽装されたユーザーが Active Directory 内のオブジェクトを変更/作成するための十分な権限を持っていることを確認する必要があります。偽装されたユーザーがドメイン管理者でない場合や、カスタム アクセス許可が設定されていない場合、このようなことはほとんどありません。

偽装をやめて、Active Directory でのアクセス許可が制限されたドメイン アカウントとしてアプリケーション プールを実行するか (ここでは最小特権を考えてください。ジョブを実行するために必要なアクセス許可のみを与えます)、コードで偽装コンテキストを作成することをお勧めします。提案されたアプリケーション プール アカウントと同じ制限を持つドメイン アカウントを手動で使用します。

このSO 回答には、コードで別のユーザーになりすますのに役立つリンクがいくつかあります。

于 2013-06-10T09:45:59.207 に答える
0

よし、やっとできた!今のところ無視している何らかの理由で、すべての反復でADを管理するのに十分な権限を持つユーザーの偽装をプログラムで使用しました。

これは、サーバー側の偽装をプログラムで実装する方法を説明するページのリンクです。

そして、私がそれをどのように使用したか以下:

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;
        }
    }

この投稿がお役に立てば幸いです。

于 2013-06-10T18:57:22.793 に答える