Active Directory UserPrincipal.Current.GetGroups() 返回本地而不是 W

本文关键字:返回 UserPrincipal Directory Current GetGroups Active | 更新日期: 2024-10-25 10:36:19

以下内容在我的本地开发框中效果很好。 但是,当我将其移动到Web服务器时,它会失败,甚至不会记录错误:

public static List<string> getAuthorizationGrps(string userName)
    {
        List<string> grps = new List<string>();
        try
        {
            PrincipalSearchResult<Principal> groups = UserPrincipal.Current.GetGroups();
            IEnumerable<string> groupNames = groups.Select(x => x.SamAccountName);
            foreach (var name in groupNames)
            {
                grps.Add(name.ToString());
            }
            return grps;
        }
        catch (Exception ex)
        {
            Log.WriteLog("Error in retriving form data: " + ex.Message);
        }
    }

我是否必须在 Web 服务器上设置权限才能查询组? 我可以在本地和 Web 服务器上毫无问题地获取当前用户。

任何想法将不胜感激,我已经为此战斗了 2 天。

Active Directory UserPrincipal.Current.GetGroups() 返回本地而不是 W

大约 6 个月前,我们遇到了类似的问题。 我们的代码调用UserPrincipal.Current.GetGroups()并在foreach循环中枚举对象。 在测试和生产中工作正常,直到有一天早上 1 个同事在执行代码时不断出现异常。 枚举 groupNames 对象开始引发 IndexOutOfRangeException。 一个小时后,我无法弄清楚出了什么问题,所以我添加了一个 kludge,称为进行 ADSI 调用的存储过程,类似于这里的第二个答案。 它并不漂亮,但它从来没有遇到过任何问题。

我假设这是你的环境

Web browser --> Web Server --> Domain Controller

除非在同一台计算机上运行Web Browser and Web ServerWeb Server and Domain Controller,否则需要设置 Kerberos 委托以使上述代码正常工作。 我猜您的开发框正在工作,因为您在同一台计算机上运行 Web 浏览器和 Web 服务器。

您可以轻松找到大量文章,教您如何为 IIS 配置 Kerberos 委派,并从 Google ASP.NET。 这是一个例子。 我不会在这里介绍细节。 关键是您的 ASP.NET 应用程序正在模拟客户端凭据并尝试使用该客户端凭据来查询 Active Directory。 如果你没有委派设置正确,Windows 将认为模拟的凭据无法访问网络。 在您的情况下,您无法访问域控制器。 这是一项安全措施。 这只是为了确保服务器不能代表网络上的最终用户执行操作,除非明确授予它具有执行此操作的权限。

另一种解决方案是更改代码。 因此,在调用 GetGroups 之前,请撤消模拟并再次成为 IIS 应用程序池帐户。 如果您的 AppPool 帐户配置为域帐户,该帐户具有足够的权限来读取 Active Directory,则可以在 Active Directory 中查询用户的组。

这是一个关于这个的斑点。 这是我认为它应该在没有任何 Kerberos 委派设置的情况下工作的代码。 不过我没有测试它。

public static List<string> getAuthorizationGrps(string userName)          
{          
    List<string> grps = new List<string>();          
    try          
    {
        var currentUser = UserPrincipal.Current;
        RevertToSelf();             
        PrincipalSearchResult<Principal> groups = currentUser.GetGroups();          
        IEnumerable<string> groupNames = groups.Select(x => x.SamAccountName);          
        foreach (var name in groupNames)          
        {          
            grps.Add(name.ToString());          
        }          
        return grps;          
    }          
    catch (Exception ex)          
    {          
        Log.WriteLog("Error in retriving form data: " + ex.Message);          
    }          
}