| 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 | |
|
|
|
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.
private static string domain = "AD1";
// Verifica se o usuário
e a senha são válidos no domínio
publicstatic 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
publicstatic 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.
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.
IIdentity wi = WindowsIdentity.GetCurrent();
// ...ou...
IPrincipal wp = Thread.CurrentPrincipal;
IPrincipal wp = new WindowsPrincipal((WindowsIdentity)wi);
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.
[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.