Quero validar um conjunto de credenciais em relação ao controlador de domínio. por exemplo:
Username: STACKOVERFLOW\joel
Password: splotchy
Método 1. Consultar o Active Directory com representação
Muitas pessoas sugerem consultar o Active Directory para algo. Se uma exceção for lançada, você saberá que as credenciais não são válidas - como é sugerido nesta questão stackoverflow .
No entanto, existem algumas desvantagens sérias nessa abordagem :
Você não está apenas autenticando uma conta de domínio, mas também fazendo uma verificação de autorização implícita. Ou seja, você está lendo propriedades do AD usando um token de representação. E se a conta válida de outra forma não tiver direitos de leitura do AD? Por padrão, todos os usuários têm acesso de leitura, mas as políticas de domínio podem ser definidas para desabilitar as permissões de acesso para contas restritas (e / ou grupos).
A vinculação ao AD tem uma sobrecarga séria, o cache do esquema do AD deve ser carregado no cliente (cache ADSI no provedor ADSI usado por DirectoryServices). Isso consome recursos da rede e do servidor AD - e é muito caro para uma operação simples como a autenticação de uma conta de usuário.
Você está contando com uma falha de exceção para um caso não excepcional e presumindo que isso significa nome de usuário e senha inválidos. Outros problemas (por exemplo, falha de rede, falha de conectividade AD, erro de alocação de memória, etc.) são então interpretados incorretamente como falha de autenticação.
Método 2. API LogonUser Win32
Outros sugeriram usar a LogonUser()
função API. Isso parece bom, mas infelizmente o usuário que faz a chamada às vezes precisa de uma permissão geralmente concedida apenas ao próprio sistema operacional:
O processo de chamada de LogonUser requer o privilégio SE_TCB_NAME. Se o processo de chamada não tiver esse privilégio, LogonUser falha e GetLastError retorna ERROR_PRIVILEGE_NOT_HELD.
Em alguns casos, o processo que chama LogonUser também deve ter o privilégio SE_CHANGE_NOTIFY_NAME habilitado; caso contrário, LogonUser falha e GetLastError retorna ERROR_ACCESS_DENIED. Este privilégio não é necessário para a conta do sistema local ou contas que são membros do grupo de administradores. Por padrão, SE_CHANGE_NOTIFY_NAME está habilitado para todos os usuários, mas alguns administradores podem desabilitá-lo para todos.
Distribuir o privilégio " Agir como parte do sistema operacional " não é algo que você queira fazer quer queira quer não - como a Microsoft aponta em um artigo da base de conhecimento :
... o processo que está chamando LogonUser deve ter o privilégio SE_TCB_NAME (no Gerenciador de usuários, esse é o direito " Agir como parte do sistema operacional "). O privilégio SE_TCB_NAME é muito poderoso e não deve ser concedido a nenhum usuário arbitrário apenas para que ele possa executar um aplicativo que precise validar credenciais.
Além disso, uma chamada para LogonUser()
falhará se uma senha em branco for especificada.
Qual é a maneira correta de autenticar um conjunto de credenciais de domínio?
Acontece que estou ligando de código gerenciado, mas esta é uma questão geral do Windows. Pode-se presumir que os clientes tenham o .NET Framework 2.0 instalado.