Si está en .NET 3.5 o superior, puede usar el nuevo System.DirectoryServices.AccountManagement
espacio de nombres (S.DS.AM) que hace que esto sea mucho más fácil de lo que solía ser.
Lea todo sobre esto aquí: Administración de los principales de seguridad de directorios en .NET Framework 3.5
Actualización: los artículos más antiguos de la revista MSDN ya no están en línea, desafortunadamente; deberá descargar el CHM para la revista MSDN de enero de 2008 de Microsoft y leer el artículo allí.
Básicamente, necesita tener un "contexto principal" (normalmente su dominio), un principal de usuario, y luego obtiene sus grupos muy fácilmente:
public List<GroupPrincipal> GetGroups(string userName)
{
List<GroupPrincipal> result = new List<GroupPrincipal>();
// establish domain context
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
// find your user
UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);
// if found - grab its groups
if(user != null)
{
PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
// iterate over all groups
foreach(Principal p in groups)
{
// make sure to add only group principals
if(p is GroupPrincipal)
{
result.Add((GroupPrincipal)p);
}
}
}
return result;
}
y eso es todo lo que hay! Ahora tiene un resultado (una lista) de los grupos de autorización a los que pertenece el usuario: iterar sobre ellos, imprimir sus nombres o lo que sea que necesite hacer.
Actualización: para acceder a ciertas propiedades, que no aparecen en el UserPrincipal
objeto, debe profundizar en el subyacente DirectoryEntry
:
public string GetDepartment(Principal principal)
{
string result = string.Empty;
DirectoryEntry de = (principal.GetUnderlyingObject() as DirectoryEntry);
if (de != null)
{
if (de.Properties.Contains("department"))
{
result = de.Properties["department"][0].ToString();
}
}
return result;
}
Actualización n. ° 2: parece que no debería ser demasiado difícil juntar estos dos fragmentos de código ... pero está bien, aquí va:
public string GetDepartment(string username)
{
string result = string.Empty;
// if you do repeated domain access, you might want to do this *once* outside this method,
// and pass it in as a second parameter!
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
// find the user
UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, username);
// if user is found
if(user != null)
{
// get DirectoryEntry underlying it
DirectoryEntry de = (user.GetUnderlyingObject() as DirectoryEntry);
if (de != null)
{
if (de.Properties.Contains("department"))
{
result = de.Properties["department"][0].ToString();
}
}
}
return result;
}
UserPrincipal
- vea mi respuesta actualizada sobre cómo obtenerla.GetAuthorizationGroups()
no encuentra grupos anidados. Para obtener realmente todos los grupos de los que un usuario determinado es miembro (incluidos los grupos anidados), intente esto:Lo uso
try/catch
porque tuve algunas excepciones con 2 de 200 grupos en un AD muy grande porque algunos SID ya no estaban disponibles. (LaTranslate()
llamada realiza una conversión de SID -> Nombre).fuente
En primer lugar, GetAuthorizationGroups () es una función excelente, pero desafortunadamente tiene 2 desventajas:
Por lo tanto, escribí una pequeña función para reemplazar GetAuthorizationGroups () con un mejor rendimiento y a prueba de errores. Realiza solo 1 llamada LDAP con una consulta utilizando campos indexados. Se puede ampliar fácilmente si necesita más propiedades que solo los nombres de grupo (propiedad "cn").
fuente
Dentro del AD cada usuario tiene una propiedad
memberOf
. Contiene una lista de todos los grupos a los que pertenece.Aquí hay un pequeño ejemplo de código:
fuente
En mi caso, la única forma en que podía seguir usando GetGroups () sin ninguna excepción era agregando al usuario (USER_WITH_PERMISSION) al grupo que tiene permiso para leer el AD (Active Directory). Es extremadamente esencial construir el PrincipalContext pasando este usuario y contraseña.
Pasos que puede seguir dentro de Active Directory para que funcione:
fuente
Esto funciona para mi
fuente
La respuesta depende del tipo de grupos que desee recuperar. El
System.DirectoryServices.AccountManagement
espacio de nombres proporciona dos métodos de recuperación de grupos:Por lo tanto,
GetGroups
obtiene todos los grupos de los que el usuario es miembro directo yGetAuthorizationGroups
todos los grupos de autorización de los que el usuario es miembro directo o indirecto .A pesar de la forma en que se nombran, uno no es un subconjunto del otro. Puede haber grupos devueltos por
GetGroups
no devueltos porGetAuthorizationGroups
y viceversa.Aquí tienes un ejemplo de uso:
fuente
Mi solución:
fuente
En caso de que Translate funcione localmente pero no de forma remota, ei group. Traducir (typeof (NTAccount)
Si desea que el código de la aplicación se ejecute utilizando la identidad de USUARIO INICIADO, habilite la suplantación. La suplantación se puede habilitar a través de IIS o agregando el siguiente elemento en web.config .
Si la suplantación está habilitada, la aplicación se ejecuta utilizando los permisos que se encuentran en su cuenta de usuario. Entonces, si el usuario que inició sesión tiene acceso a un recurso de red específico, solo entonces podrá acceder a ese recurso a través de la aplicación.
Agradezca a PRAGIM tech por esta información de su diligente video
Autenticación de Windows en asp.net Parte 87:
https://www.youtube.com/watch?v=zftmaZ3ySMc
Pero la suplantación crea mucha sobrecarga en el servidor
La mejor solución para permitir a los usuarios de ciertos grupos de red es negar el anonimato en la configuración web
<authorization><deny users="?"/><authentication mode="Windows"/>
y en su código detrás, preferiblemente en global.asax, use HttpContext.Current.User.IsInRole :
NOTA: El grupo debe escribirse con una barra invertida \ es decir, "TheDomain \ TheGroup"
fuente