【问题标题】:Impersonation to Update user AD info in an ASP.NET Forms Authenticated Site在 ASP.NET Forms Authenticated Site 中更新用户 AD 信息的模拟
【发布时间】:2011-10-15 23:00:25
【问题描述】:

我们有一个 Forms Authenticated Intranet,它向 AD 查询登录信息并将 Windows 身份的副本存储在会话中,以便以后在更新其 AD 条目时模拟用户。我们不能使用 Windows 身份验证来模拟(长话短说)。

所以登录代码是:

[DllImport("advapi32.dll")]
        public static extern bool LogonUser(String
            lpszUsername, String lpszDomain,
            String lpszPassword, int dwLogonType, int
                dwLogonProvider, out int phToken);

        public bool LoginWindowsUser(String domain, String username, String pwd, HttpSessionStateBase session)
        {

            int ret = 0;
            int l_token1;
            bool loggedOn = LogonUser(username,
                domain, pwd,
                // Logon type=LOGON32_LOGON_NETWORK_CLEARTEXT.
            3,
                // Logon provider=LOGON32_PROVIDER_DEFAULT.
            0,
                // User token for specified user is returned 
                //here.
            out l_token1);

            if (loggedOn)
            {
                IntPtr token2 = new IntPtr(l_token1);
                var l_Wid = new WindowsIdentity(token2);


                session["WindowsIdentity"] = l_Wid;
            }
            return loggedOn;
        }

然后当我们需要更新用户的广告信息时,我们会这样做:

public void UpdateUserProperty(string username, string propertyName, string propertyValue)
        {
            // Obtain the authenticated user's identity.
            var winId = (WindowsIdentity) ControllerContext.HttpContext.Session["WindowsIdentity"];
             // Start impersonating.
            using (WindowsImpersonationContext ctx = winId.Impersonate())
            {
                try
                {
                    var ds = new DirectorySearcher();
                    int ind = username.IndexOf("\\") + 1;
                    username = username.Substring(ind, username.Length - ind);

                    var filter = "(&(objectCategory=Person)(objectClass=user)";

                    if (!username.IsNullOrEmpty())
                    {
                        filter += "(samaccountname=*{0}*)".F(username);
                    }

                    filter += ")";

                    ds.Filter = filter;

                    foreach (var property in ADUserDetailsDisplay.LoadProperties())
                    {
                        ds.PropertiesToLoad.Add(property);
                    }

          ///////////// ERROR OCCURS AFTER NEXT LINE /////////////

                    var searchResult = ds.FindOne();

                    var userDirectoryEntry = searchResult.GetDirectoryEntry();

                    if (propertyValue.IsNullOrEmpty())
                    {
                        if (userDirectoryEntry.Properties[propertyName].Count > 0) userDirectoryEntry.Properties[propertyName].RemoveAt(0);
                    }
                    else if (userDirectoryEntry.Properties[propertyName].Count == 0)
                    {
                        userDirectoryEntry.Properties[propertyName].Add(propertyValue);
                    }
                    else
                    {
                        userDirectoryEntry.Properties[propertyName][0] = propertyValue;
                    }
                    userDirectoryEntry.CommitChanges();


                }
                catch (Exception ex)
                {
                    TempData.AddErrorMessage("Unable to update user: " + ex.Message);
                }
                finally
                {
                    // Revert impersonation.
                    if (ctx != null)
                        ctx.Undo();
                }
            }
            // Back to running under the default ASP.NET process identity.

        }

问题是我们收到以下错误:

无法更新用户:出现操作错误。

如果有人能指导我找到解决方案,我将不胜感激。

使用 IIS 7.5 Win2008 R2 ASP.NET MVC2

谢谢。

【问题讨论】:

    标签: c# asp.net active-directory impersonation


    【解决方案1】:

    你的上下文/搜索根在哪里告诉它你试图连接到谁/你试图搜索的位置?

    例如。

    // Bind to the users container.
    DirectoryEntry entry = new DirectoryEntry("LDAP://CN=users,DC=fabrikam,DC=com");
    // Create a DirectorySearcher object.
    DirectorySearcher mySearcher = new DirectorySearcher(entry);
    

    如果你没有这个,那么根据 MSDN,SearchRoot 的默认值为 null... MSDN 链接:http://msdn.microsoft.com/en-us/library/h9zyssd8.aspx

    【讨论】:

    • 这不是完整的答案,但导致我找到了答案。我最终做的是根据用户的帐户创建一个目录条目并将我的搜索器绑定到它。我使用模拟窗口上下文报废了。
    【解决方案2】:

    处理 AD 有时是一种 PIA。

    无论如何,请确保在运行您的应用程序的应用程序池中设置的帐户对活动目录具有管理权限,以执行用户帐户的更改。

    【讨论】:

    • 它没有,但这就是重点。我正在模拟登录用户(有权更改自己的广告信息 - 选定的字段,例如电话和地址)
    【解决方案3】:

    我们自己的@dunnry 已经解决了让 System.DirectoryServices 在 ASP.NET 下模拟运行的步骤:

    Ryann Dunn can help you here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-16
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多