我该如何去迭代组以找出给定用户是否为组的成员?检查活动目录组成员身份
我知道我可以在WindowsPrincipal对象上使用IsInRole,但由于某些原因,它并不总是为我工作,它不会出错或抛出异常,但只是返回false。
我把下面的代码放在一起,可以帮助我在可靠性方面进行改进,它在3周的测试中没有给出任何错误的结果。
附注:1:因此我无法使用GC访问AD用户名和密码。 2:可以在任何域中创建组,但在同一个林中。 3:组可以拥有来自各个域和组的用户。
感谢
KA
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern int CheckTokenMembership(int TokenHandle, byte[] PSID, out bool IsMember);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
static extern bool IsValidSid(byte[] PSID);
private bool Authenticate(XmlNodeList XmlNodeGroups)
{
bool result = false;
try
{
Dictionary<string, List<string>> Groups = GetGroups(XmlNodeGroups);
//search global catalog and get SID of the group
Byte[] sid = null;
foreach (string groupName in Groups.Keys)
{
using (DirectoryEntry entry = new DirectoryEntry("GC:"))
{
IEnumerator ie = entry.Children.GetEnumerator();
ie.MoveNext();
using (DirectorySearcher ds = new DirectorySearcher((DirectoryEntry)ie.Current))
{
ds.Filter = string.Format("(&(|(sAMAccountName={0}))(objectClass=group))", groupName);
using (SearchResultCollection resColl = ds.FindAll())
{
if (resColl.Count > 0)
{
ResultPropertyCollection resultPropColl = resColl[0].Properties;
sid = (byte[])resultPropColl["objectsid"][0];
if (sid == null || !IsValidSid(sid))
{
// log message and continue to next group continue;
}
}
else
{
// log message and continue to next group continue;
}
}
bool bIsMember = false;
if (CheckTokenMembership(0, sid, out bIsMember) == 0)
{
// log message and initiate fall back....... use Legacy
result = CheckMemberOf(XmlNodeGroups, _CurrentIdentity);
break;
}
else
{
result = bIsMember ? true : false;
if (result)
{
// debug message break;
}
else
{
// debug message
}
}
}
}
}
}
catch (Exception ex)
{
// log exception message and initiate fall back....... use Legacy
result = CheckMemberOf(XmlNodeGroups, _CurrentIdentity);
}
return result;
}</code>
我仍然使用.Net v2.0,并且没有计划将它移动到3.5。我想我们今年下半年会直接进入v4.0。 – TheOCD 2010-02-02 08:58:02
非常感谢您的回复。这正是我一直在寻找的。但是我看到的是代码太慢,因为它是递归的。代码行: //在组成员列表中找到用户 UserPrincipal user =(result.FirstOrDefault(p => p.DisplayName ==“Some Name”)as UserPrincipal); 在尝试解析包含大量用户的组时非常慢。任何帮助。 – Ashish 2010-12-20 06:08:27
@Ashish:如果你不想让它递归,那就改用'GetMembers(false)'。这应该会让事情变得相当糟糕 – 2010-12-20 07:30:06