Se você estiver no .NET 3.5 ou superior, poderá usar o novo System.DirectoryServices.AccountManagement
namespace (S.DS.AM), que torna isso muito mais fácil do que costumava ser.
Leia tudo sobre isso aqui: Gerenciando princípios de segurança de diretório no .NET Framework 3.5
Atualização: artigos mais antigos da revista MSDN não estão mais online, infelizmente - você precisará baixar o CHM para a revista MSDN de janeiro de 2008 da Microsoft e ler o artigo lá.
Basicamente, você precisa ter um "contexto principal" (normalmente seu domínio), um principal do usuário, e então obter seus grupos muito facilmente:
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;
}
e isso é tudo que existe! Agora você tem um resultado (uma lista) de grupos de autorização aos quais o usuário pertence - iterar sobre eles, imprimir seus nomes ou o que quer que você precise fazer.
Atualização: para acessar certas propriedades, que não são apresentadas no UserPrincipal
objeto, você precisa se aprofundar em 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;
}
Atualização nº 2: parece que não deve ser muito difícil colocar esses dois trechos de código juntos ... mas ok - aqui vai:
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
- veja minha resposta atualizada para saber como acessá- la.GetAuthorizationGroups()
não encontra grupos aninhados. Para realmente obter todos os grupos dos quais um determinado usuário é membro (incluindo grupos aninhados), tente o seguinte:Eu uso
try/catch
porque tive algumas exceções com 2 de 200 grupos em um AD muito grande porque alguns SIDs não estavam mais disponíveis. (ATranslate()
chamada faz um SID -> conversão de nome.)fonte
Em primeiro lugar, GetAuthorizationGroups () é uma ótima função, mas infelizmente tem 2 desvantagens:
Portanto, escrevi uma pequena função para substituir GetAuthorizationGroups () com melhor desempenho e à prova de erros. Ele faz apenas 1 chamada LDAP com uma consulta usando campos indexados. Ele pode ser facilmente estendido se você precisar de mais propriedades do que apenas os nomes dos grupos (propriedade "cn").
fonte
Dentro do AD, todo usuário tem uma propriedade
memberOf
. Este contém uma lista de todos os grupos aos quais ele pertence.Aqui está um pequeno exemplo de código:
fonte
No meu caso, a única maneira de continuar usando GetGroups () sem qualquer expcetion foi adicionando o usuário (USER_WITH_PERMISSION) ao grupo que tem permissão para ler o AD (Active Directory). É extremamente essencial construir o PrincipalContext passando este usuário e senha.
Etapas que você pode seguir dentro do Active Directory para fazê-lo funcionar:
fonte
Isso funciona para mim
fonte
A resposta depende de que tipo de grupos você deseja recuperar. O
System.DirectoryServices.AccountManagement
namespace fornece dois métodos de recuperação de grupo:Então
GetGroups
fica todos os grupos dos quais o usuário é um direto membro, eGetAuthorizationGroups
recebe todos de autorização grupos dos quais o usuário é um direto ou indireto membro.Apesar da forma como são nomeados, um não é um subconjunto do outro. Pode haver grupos retornados por
GetGroups
não retornadosGetAuthorizationGroups
e vice-versa.Aqui está um exemplo de uso:
fonte
Minha solução:
fonte
No caso de o Tradutor funcionar localmente, mas não remotamente ei group. Traduzir (typeof (NTAccount)
Se você deseja que o código do aplicativo seja executado usando a identidade LOGGED IN USER, ative a representação. A personificação pode ser habilitada através do IIS ou adicionando o seguinte elemento no web.config .
Se a representação estiver habilitada, o aplicativo será executado usando as permissões encontradas na sua conta de usuário. Portanto, se o usuário logado tiver acesso, a um recurso específico da rede, só então ele poderá acessar esse recurso através do aplicativo.
Agradeça ao PRAGIM tech por esta informação de seu diligente vídeo
Autenticação do Windows no asp.net Parte 87:
https://www.youtube.com/watch?v=zftmaZ3ySMc
Mas a representação cria muita sobrecarga no servidor
A melhor solução para permitir usuários de certos grupos de rede é negar anônimos na configuração da web
<authorization><deny users="?"/><authentication mode="Windows"/>
e em seu code behind, de preferência no global.asax, use o HttpContext.Current.User.IsInRole :
NOTA: O grupo deve ser escrito com uma barra invertida \ ou seja, "TheDomain \ TheGroup"
fonte