Autenticação em PHP usando LDAP por meio do Active Directory

104

Estou procurando uma maneira de autenticar usuários por meio de LDAP com PHP (com o Active Directory sendo o provedor). Idealmente, ele deve ser capaz de rodar no IIS 7 ( adLDAP faz isso no Apache). Alguém já havia feito algo semelhante, com sucesso?

  • Edit: Eu prefiro uma biblioteca / classe com código pronto para ir ... Seria bobagem inventar a roda quando alguém já o fez.
DV.
fonte
Acho que o drupal tem um módulo para thatr
redben

Respostas:

167

Importar uma biblioteca inteira parece ineficiente quando tudo que você precisa são essencialmente duas linhas de código ...

$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) {
  // log them in!
} else {
  // error message
}
ceejayoz
fonte
43
Algumas instalações do AD serão vinculadas com êxito se a senha fornecida estiver vazia. Atente para isso! Pode ser necessário garantir uma senha não vazia antes de tentar autenticar.
diolemo de
@diolemo Existe alguma maneira de evitar isso sem verificar se a senha está vazia?
Naftali também conhecido como Neal
@Neal Você pode usar ldap_set_optionpara fazer com que ele se comporte de maneira diferente. Talvez definindo a versão do protocolo? Você terá que experimentar. Eu pessoalmente sugiro que você verifique se há uma senha vazia de qualquer maneira, apenas por segurança.
diolemo de
@diolemo Fiz uma nova pergunta relacionada a isso.
Naftali também conhecido como Neal,
Para o editor anônimo: não, até onde sei, a higienização de entrada não é necessária aqui, como ldap_bindseria o tratamento, e os caracteres especiais não são um problema.
ceejayoz
14

Você pensaria que simplesmente autenticar um usuário no Active Directory seria um processo bastante simples usando LDAP em PHP sem a necessidade de uma biblioteca. Mas há muitas coisas que podem complicar muito rápido:

  • Você deve validar a entrada. Um nome de usuário / senha vazios passaria de outra forma.
  • Você deve garantir que o nome de usuário / senha esteja codificado corretamente ao vincular.
  • Você deve criptografar a conexão usando TLS.
  • Usando servidores LDAP separados para redundância no caso de um ficar inativo.
  • Recebendo uma mensagem de erro informativa se a autenticação falhar.

Na verdade, é mais fácil na maioria dos casos usar uma biblioteca LDAP que suporte o acima. No final das contas acabei lançando minha própria biblioteca que lida com todos os pontos acima: LdapTools (Bem, não apenas para autenticação, ela pode fazer muito mais). Ele pode ser usado da seguinte forma:

use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;

$domain = (new DomainConfiguration('example.com'))
    ->setUsername('username') # A separate AD service account used by your app
    ->setPassword('password')
    ->setServers(['dc1', 'dc2', 'dc3'])
    ->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);

if (!$ldap->authenticate($username, $password, $message)) {
    echo "Error: $message";
} else {
    // Do something...
}

A chamada de autenticação acima irá:

  • Confirme se o nome de usuário e a senha não estão vazios.
  • Certifique-se de que o nome de usuário / senha estejam codificados corretamente (UTF-8 por padrão)
  • Tente um servidor LDAP alternativo, caso um esteja inativo.
  • Criptografe a solicitação de autenticação usando TLS.
  • Forneça informações adicionais se houver falha (ou seja, conta bloqueada / desativada, etc)

Existem outras bibliotecas para fazer isso também (como Adldap2). No entanto, me senti compelido o suficiente para fornecer algumas informações adicionais, já que a resposta mais votada é, na verdade, um risco de segurança no qual confiar sem validação de entrada feita e sem usar TLS.

ChadSikorra
fonte
1
Para conexões LDAP, o TLS foi preterido em favor do StartTLS: openldap.org/faq/data/cache/605.html .
Zenlord
2
@zenlord O uso do ldaps://formato para a conexão está obsoleto. No meu exemplo, quando você especifica, setUseTls(true)ele usa o ldap://formato e emite um StartTLS usando ldap_start_tls($connection). Portanto, o próprio TLS não foi descontinuado, apenas conectando usando ldaps://(que na verdade se conecta ao LDAP por uma porta completamente diferente).
ChadSikorra
12

Eu faço isso simplesmente passando as credenciais do usuário para ldap_bind ().

http://php.net/manual/en/function.ldap-bind.php

Se a conta puder ser vinculada ao LDAP, ela é válida; se não puder, não é. Se tudo o que você está fazendo é autenticação (não gerenciamento de conta), não vejo a necessidade de uma biblioteca.

Scott Reynen
fonte
9

Eu gosto da classe Zend_Ldap , você pode usar apenas esta classe em seu projeto, sem o Zend Framework.

CMS
fonte
1
Tive o trabalho de implementar o procedimento acima para descobrir que era para gerenciar, não autenticar. Pretendo mudar para zend.auth.adapter.ldap
vdidxho