Depende en lo que quieres decir con si un usuario está en un grupo de AD. En AD, los grupos pueden ser un grupo de seguridad o un grupo de distribución. Incluso para grupos de seguridad, depende de si grupos como "Usuarios del dominio" o "Usuarios" deben incluirse en la verificación de membresía.
IsUserInSecurityGroup solo buscará grupos de seguridad y funcionará para grupos de grupos primarios como "Usuarios de dominio" y "Usuarios", y no para grupos de distribución. También resolverá el problema con grupos anidados. IsUserInAllGroup también buscará grupos de distribución, pero no estoy seguro de si se encontrarán con problemas de permisos. Si lo hace, use una cuenta de servicio que esté en WAAG (See MSDN)
La razón por la que no utilizo UserPrincipal.GetAuthorizedGroups() es porque tiene muchos problemas, como requerir que la cuenta de llamada esté en WAAG y requiriendo que no hay una entrada en 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;
}
Al igual que con la respuesta de BC, el código anterior no probará la membresía anidada –
Este código ni siquiera se compila en 3.5 C#, ¿cuál es el problema? – Justin