以下在我的本地开发框中非常有用。但是,当我将其移动到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天了。
答案 0 :(得分:1)
大约6个月前,我们遇到了类似的问题。我们的代码调用UserPrincipal.Current.GetGroups()并枚举foreach循环中的对象。在测试和生产中工作得很好,直到一天早上,当代码执行时,一个同事突然出现异常。枚举groupNames对象开始抛出IndexOutOfRangeException。一小时后无法弄清楚出了什么问题,所以我添加了一个kludge,称为存储过程,进行ADSI调用,类似于here的第二个答案。它不漂亮,但它曾经没有一个问题。
答案 1 :(得分:0)
我认为这是你的环境
Web browser --> Web Server --> Domain Controller
除非您在同一台计算机上运行Web Browser and Web Server
或Web 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);
}
}