Matéria



Acesso centralizado: PHP com autenticação via LDAP


Por Rafael Peregrino da Silva
Publicado em 08/06/2008

Este artigo foi visualizado 27214 vezes.

Versão para impressão Enviar por email



Não importa se o objetivo é escrever um aplicativo web próprio ou colaborar com uma solução de código aberto: armazenar as informações dos usuários em um diretório LDAP simplifica o gerenciamento do acesso entre diversos aplicativos, deixando a infraestrutura de TI mais consistente. A única coisa que faltava era a autenticação via LDAP...



Por Falko Benthin, Peter Kreußel e Rafael Peregrino da Silva



O LDAP é o padrão estabelecido quando se trata do armazenamento de informações de usuários e endereços e, nessa área específica, funciona de forma mais eficiente que um banco de dados. De outro lado, o PHP dispõe de uma API de comunicação com esse serviço de diretório, que é utilizada por algumas aplicações web — infelizmente uma minoria delas atualmente — para autenticação de usuários. Este artigo ilustra como programar uma conexão LDAP a aplicações PHP.



A versão do PHP utilizada deve ser compilada com a opção --with-ldap. Esse recurso pode, alternativamente, ser incluído como módulo. Qualquer que seja o caso, pode-se verificar se esse recurso está disponível usando a função phpinfo(), conforme mostra a figura 1. No repositório de extensões do PHP PEAR [1] há também a classe auth(), que simplifica a manipulação de dados via LDAP [2]. Além do suporte ao LDAP, essa classe também possibilita a autenticação via banco de dados, arquivos de senha etc. A listagem 1 ilustra como selecionar o LDAP como fonte de dados para autenticação.



A linha 2 faz a conexão da extensão PEAR. A linha 9 cria o objeto PHP necessário à realização de autenticação com os parâmetros da matriz (array) $options[] — o endereço e a porta do servidor LDAP (localhost, 389), a versão do protocolo LDAP que está sendo usada e o domínio LDAP de "base" (dc=j-hoch-3,dc=de).











Figura 1: Uma extensão conecta o LDAP ao PHP. A função phpinfo() informa se a extensão está compilada ou foi carregada como módulo.









Listagem 1:
Auth.php

01 <?php
02 require_once "Auth.php";
03 $options = array('host' => 'localhost',
04 'port' => '389',
05 'version'= 3,
06 'basedn' => 'dc=j-hoch-3, dc=de',
07 'userattr' => 'uid',
08 'useroc' => 'person');
09 $auth = new Auth('LDAP', $options,
10 $loginFunction = 'Nome da função',
11 $showLogin = true);
12 //Inicia autenticação
13 $auth->start();
14
15 if($auth->getAuth()){
16 //Código para usuários autentificados
17 }
18 else{
19 //Código para usuários não autentificados
20 }
21
22 //Desconectar usuário
23 $auth->logout();
24 ?>




Caso especial



A expressão 'useroc' => 'person' na linha 8 informa ao objeto Auth que os atributos da classe LDAP person devem ser usados na busca. Ela modifica o padrão, segundo o qual PEAR::Auth busca por dados na classe posixAccount, e que requer os campos gidNumber, homeDirectory e uidNumber. Como aplicações web não necessitam desses campos, a autenticação no exemplo anterior usa ao invés disso campo uid (User ID). Outras opções seriam o campo Common Name (cn) ou o Search Name (sn).



Se o parâmetro $showLogin na linha 9 tiver como valor true, a extensão PEAR produz automaticamente um formulário de login, caso o usuário ainda não esteja "logado" no sistema. Através de uma função, responsável pela criação do código HTML do formulário, pode-se fazer ajustes em sua aparência. É importante ressaltar que o formulário retorna o nome do usuário e a sua senha via $POST através dos campos username e password do formulário.



A listagem 2 mostra um arquivo LDIF (LDAP Directory Interchange Format), que é o formato no qual o LDAP arquiva seus dados. Ele contém dois usuários exemplo, entre eles aquele que possui as informações necessárias para autentificação. No exemplo, os dados de login são armazenados por dn:dc, uid e userpassword.









Listagem 2:
Arquivo LDIF

01 dn: cn=Falko Benthin,ou=editors,dc=j-hoch-3,dc=de
02 objectclass: top
03 objectclass: person
04 cn: Falko Benthin
05 sn: Benthin
06 uid: fbenthin
07 ou: editors
08 mail: fbenthin@j-hoch-3.de
09 l: Potsdam
10 postalcode: 14467
11 userpassword: segredo1
12
13 dn: cn=Hans Hein,ou=editors,dc=j-hoch-3,dc=de
14 objectclass: top
15 objectclass: person
16 cn: Hans Hein
17 sn: Hein
18 uid: hhein
19 ou: editors
20 mail: hhein@j-hoch-3.de
21 l: Potsdam
22 postalcode: 14467
23 userpassword: segredo2




A chamada do método $auth->start() na linha 13 da listagem 1 serve para instanciar o objeto Auth e autenticar um usuário. Para tanto, esse método realiza uma conexão anônima ao servidor LDAP e verifica se há uma entrada no diretório LDAP correspondente ao username fornecido no campo definido em userattr. Se houver exatamente uma pessoa cujos dados batam com o valor fornecido, Auth::start() tentará realizar uma conexão autenticada utilizando-se para isso do Distinguished Name e da senha inserida através do formulário.



Se todas as informações baterem, a sessão PHP do visitante do site é classificada como válida, e $auth->getAuth() passa a fornecer o estado true até a sessão do usuário expirar — conforme timeout configurado em php.ini — ou quando o próprio usuário deixar a sessão, através da chamada de $auth->logout(). A variável $username contém os nomes dos usuários que serão solicitados com mais freqüência pelas aplicações web em tempo de execução.



Próximos capítulos



Vimos que, com o módulo PEAR Auth, é fácil realizar autenticação consultando uma base LDAP. Entretanto, ainda falta alguma coisa para que uma aplicação web seja capaz de consultar a base LDAP: ainda é necessário substituir no código PHP as chamadas do método getAuth(), nas quais a aplicação verifica especificamente se o usuário ainda está logado no sistema. O mesmo vale para as partes do código, através das quais o programa lê os nomes dos usuários no banco de dados.



Qual será o nível de dificuldade desse tipo de alteração em um caso concreto, vai depender muito mais de o quanto a aplicação tenha sido desenvolvida de maneira estruturada e sistemática. Se o sistema tiver sido desenvolvido de modo que para a autenticação seja sempre realizada através de uma função ou método, então as modificações requeridas no código serão pequenas, e as dificuldades de alteração deverão ser mínimas. Aliás, esse é o método preferível em todos os casos, já que assim a aplicação poderá utilizar um sem-número de backends de sistemas de autenticação, que serão assim conectados ao sistema através de uma camada de abstração.



Um debugger (software de depuração de erros) que permita executar o código passo-a-passo, é uma boa ferramenta, para entender a aplicação. O mais confortável nesse caso para o PHP é o uso do Eclipse, com as extensões PHP Development Tools [3] e o debugger de executáveis [4] gratuito da empresa Zend (ver figura 2). Há também uma versão livre do debugger DBG [5], e o Xdebug está disponível para download e licenciado sob a licença PHP [6].











Figura 2: A combinação do Eclipse, das PHP Development Tools e do debugger da empresa Zend fornecem um ambiente bastante adequado de desenvolvimento, que facilita entender o funcionamento de aplicações web escritas em PHP.



Um exemplo real



A listagem 3 mostra um exemplo de código que não usa LDAP, por meio do qual o banco de dados de fotografias Photo Organizer 2.33 [7] verifica se o usuário já está ou não logado no sistema. Esse trecho de código fonte — muito freqüentemente anexado via include a sistemas de gerenciamento web de fotografias —, está no arquivo site.php, e mostra aquilo que um desenvolvedor interessado em ajustar o código fonte de uma aplicação web deveria procurar, para que o uso de LDAP passe a ser realizado: o Photo Organizer se utiliza para gerenciar a sessão do usuário de um cookie próprio (linha 1 da listagem 3). O resto do código ilustra a realização de uma consulta ao banco de dados após a filtragem dos dados através da função pg_escape_string().







Listagem 3:
Gerenciamento de sessão em
um Photo Organizer

01 if (isset($_COOKIE[$po_cookie])) {
02 $session_id = pg_escape_string($_COOKIE[$po_cookie]);
03
04 $res = pg_query($dbh, "SELECT identifier, type,
05 preferences, username, first_name,
06 last_name, password
07 FROM users
08 WHERE session_id='$session_id'");
09 if (($res != FALSE) && pg_num_rows($res)) {
10 $row = pg_fetch_assoc($res);
11 $po_user['id'] = $row['identifier'];
12 $po_user['type'] = $row['type'];
13 $po_user['session'] = $session_id;
14 $po_user['prefs'] = $row['preferences'];
15 $po_user['username'] = $row['username'];
16 $po_user['first_name'] = $row['first_name'];
17 $po_user['last_name'] = $row['last_name'];
18 $po_user['password'] = $row['password'];
19 }
20 }




Outras aplicações usam as funções de gerenciamento de sessões nativas do PHP, que trabalham ou com cookies ou com parâmetros fornecidos na URL. Uma sessão desse tipo é normalmente iniciada com session_start() ou através da opção de inicialização (fornecida através do arquivo .ini) session.auto_start, que pode ser alterada em tempo de operação.



Referências





Gostou? Curta e Compartilhe!

Versão para impressão Enviar por email

Comentários

lançamento!

LM 119 | Backup e Restauração




Impressa esgotada
Comprar Digital  R$ 10,90 Digital

  1. Soluti Certificação Digital em busca de especialista Linux

    Publicado em 19/04/2017 às 17:18 | 597401 leituras

  1. Seminário sobre gestão de privilégios do Linux dá direito a certificado CPE

    Publicado em 23/05/2017 às 10:35 | 514723 leituras

  1. Baixe o curso de shell script do Julio Cezar Neves

    Publicado em 07/04/2008 às 19:41 | 492342 leituras

  1. 4Linux abre vagas para Líder Técnico em São Paulo e Brasília

    Publicado em 25/07/2017 às 14:12 | 359772 leituras

  1. Novo evento "Universidade Livre" será realizado em Belém/PA em 06/05/2017

    Publicado em 28/04/2017 às 11:19 | 305186 leituras

  1. Velocidade da internet cresce 13% no 1º trimestre

    Publicado em 24/06/2015 às 16:14 | 8626 leituras

  1. Linux Pro Magazine adquire a Linux Magazine EUA

    Publicado em 11/06/2008 às 18:52 | 12582 leituras

  1. Alibaba abre novo centro de dados de computação em nuvem

    Publicado em 03/09/2014 às 11:27 | 11318 leituras

  1. O retorno do filho pródigo

    Publicado em 23/12/2011 às 17:36 | 15950 leituras

  1. Amazon Web Services lança serviço de busca em nuvem para o Brasil

    Publicado em 16/04/2012 às 18:36 | 13162 leituras

whitepapers

mais whitepapers