Acesso a LDAP

7 respostas
R

Olá,

Estou desenvolvendo uma aplicação que esta se autenticando numa base LDAP, no caso especifico é um Active Directory.
Estou tendo dificuldades em acessar a “node” especifico que representa casa usuario para efetivar a autenticação dele. E a propria autenticação do server esta estranha. Eu nao consigo me autenticar com a minha senha, mas consigo me autenticar sem senha nenhuma. Alguem poderia me ajudar nesse ponto. Estou procurando tb um browser de LDAP mas nao estou encontrando nenhum legal.

Desde já, agredeço.

Ricardo.

7 Respostas

F

Eu usava esse browser LDAP. É simples, atendeu minhas necessidades.

R

Muito obrigado. Vou fazer alguns testes com ele e ver se consigo realizar a autenticação.

Abraços,

Ricardo.

A

Olá Ricardo,

Acredito que primeiro você precise se logar no Active Directory com acesso de administrador. Uma vez conectado, faça uma consulta pelo username e senha fornecidos pelo utilizador.
Segue um exemplo de código que pode ser útil:

import java.util.Hashtable;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class LdapAuthentication {

	/**
	 * Classe que realiza a conexão e autenticação ao LDAP
	 * 
	 * @author Adriano Anderson
	 */

	/*
	 * Singleton
	 */
	protected static LdapAuthentication instanceLdap;

	/*
	 * Implementação do Initial context para LDAP
	 */
	public static String INITIAL_CTX = "com.sun.jndi.ldap.LdapCtxFactory";

	/*
	 * Servidor LDAP
	 */
	public static String SERVIDOR = "ldap://ENDERECO DO SERVIDOR:389";

	/*
	 * Tipo de conexão realizada
	 */
	public static String CONNECTION_TYPE = "simple";

	/*
	 * Nome distinto do admin
	 */
	public static String ADMIN_DN = NODE PRINCIPAL DE ACESSO;

	/*
	 * Senha
	 */
	public static String ADMIN_PW = SENHA ADMIN;

	/*
	 * Diretório Base
	 */
	public static String BASE_DN = NODE BASE UTILIZADORES;

	/*
	 * Mensagem de Erro de Conexão ao Ldap
	 */
	public static String MSG_ERROR_LDAP_CONNECTION = "Não foi possível obter um contexto LDAP";

	/*
	 * Mensagem de Erro sobre Validação do Login e Password
	 */
	public static String MSG_ERROR_LDAP_VALIDATION_USER = "Username ou Password Inválida";

	private LdapAuthentication() {
		super();
	}

	/**
	 * Obtém a mesma instância de LdapAuthentication para todas as chamadas
	 * 
	 * @author Adriano Anderson
	 * @return um objeto LdapAuthentication
	 */
	public static LdapAuthentication getInstance() {

		if (instanceLdap == null) {
			instanceLdap = new LdapAuthentication();
		}

		return instanceLdap;
	}

	/**
	 * Método responsável por realizar a chamada para autenticação via ldap do
	 * login e password passados como parâmetros.
	 * 
	 * @author Adriano Anderson
	 */
	public boolean authentication(String login, String password) {

		DirContext ctx = null;
		SearchControls sc = null;
		String filtro = null;
		NamingEnumeration cursor = null;
		boolean bResult = false;

		/*
		 * Cria conexão padrão com LDAP
		 */
		ctx = createLdapConnection();

		if (ctx != null) {

			sc = new SearchControls();
			sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
			/*
			 * Define atributos de retorno da consulta
			 */
			String[] atributosParaRetornar = { "distinguishedName" };
			sc.setReturningAttributes(atributosParaRetornar);
			/*
			 * Especifica login para consulta
			 */
			filtro = "(&(sAMAccountName=" + login + "))";

			try {
				cursor = ctx.search(BASE_DN, filtro, sc);

				if (cursor.hasMoreElements()) {

					SearchResult result = (SearchResult) cursor.nextElement();
					Attributes att = result.getAttributes();
					String dn = (String) att.get("distinguishedName").get();

					/*
					 * Se o login existe, tenta autenticar no LDAP com a senha
					 * fornecida pelo usuário
					 */
					bResult = validateUser(dn, password);
				}

			} catch (NamingException e) {
				System.out.println(MSG_ERROR_LDAP_CONNECTION);
				e.printStackTrace();
			}
		}
		return bResult;
	}

	/**
	 * Método responsável por realizar a conexão padrão com o Ldap.
	 * 
	 * @author Adriano Anderson
	 */
	private DirContext createLdapConnection() {

		DirContext ctx = null;
		Hashtable env = new Hashtable();

		// Especifica INITIAL CONTEXT
		env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CTX);

		// Especifica o IP/Nome e a porta do servidor LDAP
		env.put(Context.PROVIDER_URL, SERVIDOR);

		// Usuário ADMIN
		env.put(Context.SECURITY_PRINCIPAL, ADMIN_DN);

		// Senha ADMIN
		env.put(Context.SECURITY_CREDENTIALS, ADMIN_PW);

		// Tipo de Conexão
		env.put(Context.SECURITY_AUTHENTICATION, CONNECTION_TYPE);

		try {
			// Cria um Initial Context
			ctx = new InitialDirContext(env);
		} catch (NamingException e) {
			System.out.println(MSG_ERROR_LDAP_CONNECTION);
			e.printStackTrace();
		}
		return ctx;
	}

	/**
	 * Método responsável por realizar a validação do login no Ldap. O campo dn
	 * é distinguished name formado anteriormente a partir da consulta do login
	 * no Ldap.
	 * 
	 * @author Adriano Anderson
	 */
	private boolean validateUser(String dn, String senha) {

		DirContext ldapCtx = null;
		boolean bResult = false;

		Hashtable env = new Hashtable();

		// Especifica INITIAL CONTEXT
		env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CTX);

		// Especifica o IP/Nome e a porta do servidor LDAP
		env.put(Context.PROVIDER_URL, SERVIDOR);

		// Ldap Distingued Name
		env.put(Context.SECURITY_PRINCIPAL, dn);

		// Senha Usuário
		env.put(Context.SECURITY_CREDENTIALS, senha);

		// Tipo de Conexão
		env.put(Context.SECURITY_AUTHENTICATION, CONNECTION_TYPE);

		try {
			// Cria um Initial Context
			ldapCtx = new InitialDirContext(env);
		} catch (AuthenticationException auEx) {
			System.out.println(MSG_ERROR_LDAP_VALIDATION_USER);
			auEx.printStackTrace();
		} catch (NamingException ne) {
			System.out.println(MSG_ERROR_LDAP_CONNECTION);
			ne.printStackTrace();
		} finally {

			if (ldapCtx != null) {
				bResult = true;
			}
		}

		return bResult;
	}
}

Boa Sorte!
Adriano

E

Ricardo,

Para fazer autenticação no LDAP (Active Directory) não é necessária a comparação da senha dentro do AD, até porque essa informação não fica disponvel e mesmo que estivesse, ela com certeza estaria criptografada.

Mas ai você pergunta, como é que vou saber se a senha é valida ?

Simples, se você com um usuário valido conseguir se logar através da sua aplicação, quer dizer que a senha dele esta correta, perceba que não é necessário conectar com o administrador para que o teste de conexão funcione, qualquer usuário do domínio irá funcionar.

Faça um teste e coloque o resultado pra gente.

Dessa forma, você consegue realizar a autenticação.

Abraços,

Eduardo Cerqueira

R

PessoALL,

Valeu mesmo. Estou fazendo a implementação disso agora e vou mandar uma resposta pra voces.

Abraços,

Ricardo.

A

Olá,

Acho que me expressei mal, quando falei

… uma vez conectado, faça uma consulta pelo username e senha fornecidos pelo utilizador …

quis dizer que deveria se conectar com a senha do usuário e o respectivo node recuperado do username passado como parâmetro, conforme está descrito no código.
Mas é claro que existem outras maneiras de implementação, melhores e piores.

Adriano Anderson.

R

ai galera to com o mesmo problema só que aqui nao é um AD no meu caso estou usando openLDAP que acaba dando na mesma, os dois fazem a mesma coisa.

o meu problema e o seguinte, eu sei que o usuario uid=rodrigopmatias,ou=usuario,dc=sede,dc=setas tem a senha gravada no ldap 1234 em 4 campos, sambaLMPassword(LMHASH), sambaNTPassword(MD4) e userPassword(Criptografado) mas a autenticação nunca da certo, será se alguem tem um exemplo simples ai que possa destrinchar e disponinbilizar os ldifs para estudo?

Criado 10 de novembro de 2006
Ultima resposta 10 de nov. de 2006
Respostas 7
Participantes 5