c# asp.net active-directory .net-3.5 active-directory-group

Vea si el usuario es parte del grupo de Active Directory en C#+ Asp.net



active-directory .net-3.5 (13)

Necesito una forma de ver si un usuario es parte de un grupo de directorio activo de mi aplicación .Net 3.5 asp.net c #.

Estoy usando el ejemplo de autenticación ldap estándar de msdn pero realmente no veo cómo compararlo con un grupo.


Con 3.5 y System.DirectoryServices.AccountManagement esto es un poco más limpio:

public List<string> GetGroupNames(string userName) { var pc = new PrincipalContext(ContextType.Domain); var src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc); var result = new List<string>(); src.ToList().ForEach(sr => result.Add(sr.SamAccountName)); return result; }


El siguiente código funcionará en .net 4.0

private static string[] GetGroupNames(string userName) { List<string> result = new List<string>(); using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN")) { using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc)) { src.ToList().ForEach(sr => result.Add(sr.SamAccountName)); } } return result.ToArray(); }


Depende de a qué te refieras 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 tipos de 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 ( consulte MSDN )

La razón por la que no utilizo UserPrincipal.GetAuthorizedGroups () es porque tiene muchos problemas, como requerir que la cuenta de llamadas esté en WAAG y que no haya una entrada en SidHistory ( consulte el comentario de David Thomas )

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; }


La solución más simple

PrincipalContext pc = new PrincipalContext((Environment.UserDomainName == Environment.MachineName ? ContextType.Machine : ContextType.Domain), Environment.UserDomainName); GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "{GroupName}"); UserPrincipal up = UserPrincipal.FindByIdentity(pc, Environment.UserName); up.IsMemberOf(gp);


Brandon Johnson, me encantó, utilicé lo que tenías, pero hice el siguiente cambio:

private static string[] GetGroupNames(string domainName, string userName) { List<string> result = new List<string>(); using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domainName)) { using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(principalContext, userName).GetGroups(principalContext)) { src.ToList().ForEach(sr => result.Add(sr.SamAccountName)); } } return result.ToArray(); }


Este método puede ser útil si está tratando de determinar si el usuario actual autenticado por Windows tiene un rol particular.

public static bool CurrentUserIsInRole(string role) { try { return System.Web.HttpContext.Current.Request .LogonUserIdentity .Groups .Any(x => x.Translate(typeof(NTAccount)).ToString() == role); } catch (Exception) { return false; } }


Aquí está mi 2 centavos.

static void CheckUserGroup(string userName, string userGroup) { var wi = new WindowsIdentity(userName); var wp = new WindowsPrincipal(wi); bool inRole = wp.IsInRole(userGroup); Console.WriteLine("User {0} {1} member of {2} AD group", userName, inRole ? "is" : "is not", userGroup); }


Esto parece mucho más simple:

public bool IsInRole(string groupname) { var myIdentity = WindowsIdentity.GetCurrent(); if (myIdentity == null) return false; var myPrincipal = new WindowsPrincipal(myIdentity); var result = myPrincipal.IsInRole(groupname); return result; }


La solución de Nick Craver no funciona para mí en .NET 4.0. Aparece un error sobre un AppDomain descargado. En lugar de usar eso, utilicé esto (solo tenemos un dominio). Esto verificará grupos de grupos así como la membresía directa del grupo.

using System.DirectoryServices.AccountManagement; using System.Linq; ... using (var ctx = new PrincipalContext(ContextType.Domain, yourDomain)) { using (var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, yourGroup)) { bool isInRole = grp != null && grp .GetMembers(true) .Any(m => m.SamAccountName == me.Identity.Name.Replace(yourDomain + "//", "")); } }


var context = new PrincipalContext(ContextType.Domain, {ADDomain}, {ADContainer}); var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, {AD_GROUP_NAME}); var user = UserPrincipal.FindByIdentity(context, {login}); bool result = user.IsMemberOf(group);


Si desea verificar la pertenencia a los grupos de usuarios, incluidos los grupos anidados que están indirectamente vinculados al grupo padre del usuario, puede intentar usar las propiedades "tokenGroups" de la siguiente manera:

Using System.DirectoryServices public static bool IsMemberOfGroupsToCheck(string DomainServer, string LoginID, string LoginPassword) { string UserDN = "CN=John.Doe-A,OU=Administration Accounts,OU=User Directory,DC=ABC,DC=com" string ADGroupsDNToCheck = "CN=ADGroupTocheck,OU=Administration Groups,OU=Group Directory,DC=ABC,DC=com"; byte[] sid, parentSID; bool check = false; DirectoryEntry parentEntry; DirectoryEntry basechildEntry; string octetSID; basechildEntry = new DirectoryEntry("LDAP://" + DomainServer + "/" + UserDN, LoginID, LoginPassword); basechildEntry.RefreshCache(new String[] { "tokenGroups" }); parentEntry = new DirectoryEntry("LDAP://" + DomainServer + "/" + ADGroupsDNToCheck, LoginID, LoginPassword); parentSID = (byte[])parentEntry.Properties["objectSID"].Value; octetSID = ConvertToOctetString(parentSID, false, false); foreach(Object GroupSid in basechildEntry.Properties["tokenGroups"]) { sid = (byte[])GroupSid; if (ConvertToOctetString(sid,false,false) == octetSID) { check = true; break; } } basechildEntry.Dispose(); parentEntry.Dispose(); return check; }


Puedes probar el siguiente código:

public bool Check_If_Member_Of_AD_Group(string username, string grouptoCheck, string domain, string ADlogin, string ADpassword) {         try {                 string EntryString = null;         EntryString = "LDAP://" + domain;                 DirectoryEntry myDE = default(DirectoryEntry);                 grouptoCheck = grouptoCheck.ToLower();                         myDE = new DirectoryEntry(EntryString, ADlogin, ADpassword);                 DirectorySearcher myDirectorySearcher = new DirectorySearcher(myDE);                 myDirectorySearcher.Filter = "sAMAccountName=" + username;                 myDirectorySearcher.PropertiesToLoad.Add("MemberOf");                 SearchResult myresult = myDirectorySearcher.FindOne();                 int NumberOfGroups = 0;                 NumberOfGroups = myresult.Properties["memberOf"].Count - 1;                 string tempString = null;                 while ((NumberOfGroups >= 0)) {                         tempString = myresult.Properties["MemberOf"].Item[NumberOfGroups];             tempString = tempString.Substring(0, tempString.IndexOf(",", 0));                         tempString = tempString.Replace("CN=", "");                         tempString = tempString.ToLower();             tempString = tempString.Trim();                         if ((grouptoCheck == tempString)) {                                                     return true;             }                                         NumberOfGroups = NumberOfGroups - 1;         }                             return false;     }     catch (Exception ex) {                 System.Diagnostics.Debugger.Break();     }     //HttpContext.Current.Response.Write("Error: <br><br>" & ex.ToString) }