Por Leonardo M. Pessoa
aetheris@terra.com.br
Leonardo M. Pessoa é Analista de Sistemas do SERPRO, trabalha a 2 anos com a tecnologia .NET (C# e VB.NET e segurança) e é membro da comunidade BrasilDotNet ( http://www.brasildotnet.com ). Visite meu blog no theSpoke: http://br.thespoke.net/MyBlog/Harkos/MyBlog.aspx

Autenticação e autorização de usuários com AD

Sempre me interessei muito por questões de segurança, principalmente em relação à permissão de uso das aplicações. Acredito que a autenticação e autorização de usuários é uma das primeiras coisas que se pensa no desenvolvimento de uma aplicação (mesmo que não seja a primeira a ser implementada).

Apesar de todo o meu interesse, só tirei tempo para estudar as vantagens do .NET (nesse sentido) recentemente. E as vantagens são muitas.

Active Directory

Desde que a MS lançou o Windows 2000, existe o Active Directory (AD). Quem já o estudou sabe que ele é baseado principalmente num protocolo pouco utilizado na Internet, que é o LDAP. Sua função é, basicamente, administrar usuários, grupos, e outros elementos de segurança de um domínio de forma simples. A grande vantagem é a interoperabilidade, uma vez que é possível substituir o AD por outro servidor LDAP com algum trabalho.

Para tanto, o .NET inclui um namespace apenas para facilitar o trabalho com AD e LDAP,  System.DirectoryServices, incluindo LDAP v3.  Nos exemplos a seguir, usaremos o domínio fictício AD1.

private static string domain = "AD1";

// Verifica se o usuário e a senha são válidos no domínio
public
static bool LogonValid(string userName, string password) {
  DirectoryEntry de
= new
DirectoryEntry(null, domain +
   
"\\" +
userName, password);
  try
{
    object
o = de.NativeObject;
    DirectorySearcher ds
= new
DirectorySearcher(de);
    ds
.Filter = "samaccountname=" +
userName;
    ds
.PropertiesToLoad.Add("cn"
);
    SearchResult sr
= ds.
FindOne();
    if
(sr == null) throw new Exception();
    return
true;
  }
catch
{
    return
false;
  }
}

// Verifica se o usuário pertence a um certo grupo
public
static bool IsInRole(string userName, string role) {
  try
{
    role
= role.ToLowerInvariant();

    DirectorySearcher ds
= new DirectorySearcher(new DirectoryEntry(null));
    ds.Filter = "samaccountname=" + userName;
    SearchResult sr = ds.
FindOne();
    DirectoryEntry de =
sr.
GetDirectoryEntry();
    PropertyValueCollection dir
= de.Properties["memberOf"
];
    for
(int i = 0; i < dir.Count; ++i) {
      string
s = dir[i].ToString().Substring(3);
      s
= s.Substring(0, s.IndexOf(',')).
ToLowerInvariant();
      if
(s == role) return true;
    }
    throw
new Exception();
  }
catch
{
    return
false;
  }
}

Os métodos foram dispostos para trabalhar em uma única aplicação, mas podem ser usados na implementação de classes adequadas ao trabalho com logons e permissões. Também é possível usar estes códigos para autenticar usuários em páginas ASP.NET utilizando Forms Authentication, mas isso também é assunto para outro artigo.

Deixa com o Windows

Aplicações podem se beneficiar ainda mais facilmente do Active Directory através de classes mais simples, evitando inclusive a necessidade de um logon exclusivo da aplicação. Deve-se ter em mente, entretanto, que essa solução passa a depender de um servidor Windows.

Como isso é possível? Através do próprio logon do Windows, sem que haja necessidade de redigitar informações, tudo através do namespace System.Security.Principal, e ainda de duas formas:

IIdentity wi = WindowsIdentity.GetCurrent();
IPrincipal wp = new
WindowsPrincipal((WindowsIdentity)wi);

// ...ou...

IPrincipal wp = Thread.CurrentPrincipal;
IIdentity wi
= wp.Identity;

A partir desse ponto, é possível verificar se o usuário pertence ou não a um grupo de usuários através do método IsInRole, definido na interface IPrincipal. Vale lembrar que os grupos de domínios devem ser qualificados (ex. "AD1\Administrators"). Grupos não qualificados são checados na máquina local.

A chamada ao método IsInRole é apenas uma alternativa. Métodos e classes ainda podem ser bloqueados através do atributo PrincipalPermissionAttribute, podendo liberar o acesso a um usuário ou grupo específico ou apenas se o usuário está autenticado (lembre-se que no Windows 9x/Me o usuário pode cancelar o logon).

[PrincipalPermission(SecurityAction.Demand, Role="AD1\\Administrators")]

[PrincipalPermission(SecurityAction.Demand, User="AD1\\harkos")]

[PrincipalPermission(SecurityAction.Demand, Authenticated=true )]

Também é possível utilizar a identidade do Windows no processo de autenticação de aplicações ASP.NET dentro de uma intranet, caso ainda mais simples de configurar. Basta editar as seguintes linhas no arquivo web.config:

<authentication mode="Windows"/>
<authorization>
   <allow roles="AD1\Administrators"/>
</authorization>

<identity impersonate="true"/>

Se a última linha for adicionada, o processo ASP.NET responsável pelas solicitações do usuário irá assumir a identidade do mesmo, permitindo o uso do atributo PrincipalPermissionAttribute nos métodos e classes que compõem a aplicação.

Utilizar a autenticação e autorização de usuário integrada do Windows/Active Directory é excelente para aplicações que funcionam dentro de uma empresa, tal como uma folha de pagamento ou contabilidade geral, facilitando a administração e delegação de tarefas a uma conta do sistema, evitando uma nova senha. Isso é o que se conhece como single sign-on. Claro que nada disso se aplica se os usuários não precisam ou não devem ser associados a contas de usuários, tais como usuários externos em um site. Nestes casos, uma implementação maior, podendo ou não exigir um banco de dados é mais adequado.

Dicas para quem está começando:
Veja os próximos eventos
que você não pode perder :

22/11/2008 SQL Launch -
Linhares - ES
Por : devASPNet


22/11/2008 SQL Launch- SQL Server 2008
Rio Paranaiba - Viçosa - MG
Por : devASPNet


22/11/2008 SQL Launch - SQL Server 2008
Volta Redonda - RJ
Por : devASPNet


22/11/2008 SQL Launch- SQL Server 2008
Franca - SP
Por : devASPNet


22/11/2008 SQL Launch - SQL Server 2008
Canoinhas - SC
Por : devASPNet


22/11/2008 SQL Launch - SQL Server 2008
Tefé - AM
Por : devASPNet


25/11/2008 SQL Launch - SQL Server 2008
Rio de Janeiro - RJ
Por : devASPNet


27/11/2008 SQL Lauch- SQL Server 2008
São Paulo - SP
Por : devASPNet


28/11/2008 SQL Launch - SQL Server 2008
São Paulo - SP
Por : devASPNet


29/11/2008 SQL Launch- SQL Server 2008
Pedro Leopoldo - MG
Por : devASPNet


29/11/2008 SQL Launch- SQL Server 2008
Petropolis - RJ
Por : devASPNet


29/11/2008 SQL Launch
Floriano - PI
Por : devASPNet


29/11/2008 SQL Launch - SQL Server 2008
Rio de Janeiro - RJ
Por : devASPNet


29/11/2008 SQL Launch - SQL Server 2008
Natal - RN
Por : devASPNet


29/11/2008 SQL Launch- SQL Server 2008
Santa Maria - RS
Por : devASPNet


29/11/2008 SQL Launch
Ituiutaba - MG
Por : devASPNet


5/12/2008 Cloud Computing e o Windows Azure
São Paulo - SP
Por : devASPNet


6/12/2008 SQL Server 2008 Community Launch
São Paulo - SP
Por : devASPNet

Leituras imperdíveis para quem está começando:

º Otimizando a performance no ASP.NET::..
º Criando objetos de paginação personalizados na grid::..
º Uma cesta de compras em ASP.NET::..
º Utilizando o Refresh de parâmetros no .NET::..
º ASP.NET FORMS Authentication::..
º Utilizando propriedades dinâmicas no .NET::..
º Corrigindo problemas de deleção em grid com paginação::..
º Cuidado com os componentes de validação::..
º Otimizando o InitializeComponent::..
º Movendo fonte de aplicações entre máquinas::..
º Agilizando a performance da IDE do VS.NET::..
º Utilizando Short Circuit no VB.NET::..


























  Parceiros:
20% de desconto para os membros do grupo na aquisição de livros e inscrição para eventos

Receba dicas de programação e programação .NET:
E-mail:
Incluir Excluir