It depends on what you mean if the user is in an AD group. In AD, groups can be a security group or a distribution group. Even for security groups, this depends on whether groups such as Domain Users or Users should be included in the membership check.
IsUserInSecurityGroup will only check security groups and will work for primary group groups such as Domain Users and Users, not distribution groups. It will also solve the problem with nested groups. IsUserInAllGroup will also check distribution groups, but I'm not sure if you run into permission problems. If you do, use the service account located in WAAG ( See MSDN )
The reason I am not using UserPrincipal.GetAuthorizedGroups () is because it has a lot of problems, such as requiring that the calling account be in WAAG and require that there is no entry in SidHistory ( See David Thomas comment )
public bool IsUserInSecurityGroup(string user, string group) { return IsUserInGroup(user, group, "tokenGroups"); } public bool IsUserInAllGroup(string user, string group) { return IsUserInGroup(user, group, "tokenGroupsGlobalAndUniversal"); } private bool IsUserInGroup(string user, string group, string groupType) { var userGroups = GetUserGroupIds(user, groupType); var groupTokens = ParseDomainQualifiedName(group, "group"); using (var groupContext = new PrincipalContext(ContextType.Domain, groupTokens[0])) { using (var identity = GroupPrincipal.FindByIdentity(groupContext, IdentityType.SamAccountName, groupTokens[1])) { if (identity == null) return false; return userGroups.Contains(identity.Sid); } } } private List<SecurityIdentifier> GetUserGroupIds(string user, string groupType) { var userTokens = ParseDomainQualifiedName(user, "user"); using (var userContext = new PrincipalContext(ContextType.Domain, userTokens[0])) { using (var identity = UserPrincipal.FindByIdentity(userContext, IdentityType.SamAccountName, userTokens[1])) { if (identity == null) return new List<SecurityIdentifier>(); var userEntry = identity.GetUnderlyingObject() as DirectoryEntry; userEntry.RefreshCache(new[] { groupType }); return (from byte[] sid in userEntry.Properties[groupType] select new SecurityIdentifier(sid, 0)).ToList(); } } } private static string[] ParseDomainQualifiedName(string name, string parameterName) { var groupTokens = name.Split(new[] {"\\"}, StringSplitOptions.RemoveEmptyEntries); if (groupTokens.Length < 2) throw new ArgumentException(Resources.Exception_NameNotDomainQualified + name, parameterName); return groupTokens; }
Terry Tsay Jan 30 '13 at 21:07 2013-01-30 21:07
source share