活动目录UserPrincipal.Current.GetGroups()返回本地而非Web服务器上的组

时间:2012-08-07 12:33:40

标签: c# asp.net active-directory

以下在我的本地开发框中非常有用。但是,当我将其移动到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服务器上都没有问题。

任何想法都会受到高度赞赏,我现在已经打了2天了。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我认为这是你的环境

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

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

您可以轻松找到大量文章,教您如何为Google配置IIS和ASP.NET的Kerberos委派。这是one example。我不会在这里详述。关键是您的ASP.NET应用程序正在模拟客户端凭据并尝试使用该客户端凭据来查询Active Directory。如果你没有 委派设置正确,Windows会认为您的模拟凭据无法访问网络。在您的情况下,您无法访问域控制器。这是一项安全措施。这只是为了确保服务器不能代表网络上的最终用户做任何事情,除非明确授权服务器有权这样做。

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

这是blob谈论这个问题。这是我认为它应该在没有任何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);          
    }          
}