如何重复群组以确定某个用户是否是某个群组的成员?
我知道我可以在WindowsPrincipal对象上使用IsInRole但由于某种原因它并不总是对我有用,它不会出错或抛出异常但只返回false。
我已将来自网络的代码放在一起,可以帮助我在可靠性方面改进它,它在3周的测试中没有给出任何错误的结果。
附注:1:我无法访问AD用户名和密码,因此使用GC。 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>
答案 0 :(得分:2)
您使用的是.NET 3.5吗?如果是这样,请查看MSDN杂志文章Managing Directory Security Principals in the .NET Framework 3.5。它显示了AD中的用户和群组变得容易多了。
至于你的要求 - 你可以
所有这一切都可以在System.DirectoryServices.AccountManagement
命名空间的帮助下轻松完成:
// establish a context - define a domain (NetBIOS style name),
// or use the current one, when not specifying a specific domain
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find the group in question
GroupPrincipal theGroup = GroupPrincipal.FindByIdentity(ctx, "nameOfGroup");
// recursively enumerate the members of the group; making the search
// recursive will also enumerate the members of any nested groups
PrincipalSearchResult<Principal> result = theGroup.GetMembers(true);
// find the user in the list of group members
UserPrincipal user = (result.FirstOrDefault(p => p.DisplayName == "Some Name") as UserPrincipal);
// if found --> user is member of this group, either directly or recursively
if(user != null)
{
// do something with the user
}
答案 1 :(得分:0)
我尝试将上面的代码片段用于3.5框架,而我的编译器认为这行不正确:
// find the user in the list of group members
UserPrincipal user = (result.FirstOrDefault(p => p.DisplayName == adUser) as UserPrincipal);
具体来说就是result.FirstOfDefault,它说这不是一个有效的选项。
谢谢!