Erro de troca de senha no LDAP com JNDI

Boa tarde amigos,

Tenho uma aplicação que possui uma funcionalidade de troca de senha, onde troca a senha do LDAP com JNDI, mas está apresentando o erro abaixo quando tento trocar a senha.

Erro:

AlteraSenhaPortlet.changePassword: javax.naming.NameNotFoundException: object does not exist

Método:


    public void changePassword(String uid, String newPasswd) throws NamingException {
        
    	logger.debug("Iniciando o método changePassword ...");
    	System.out.println("newPasswd: " + newPasswd);
    	
    	BasicAttributes attrs = new BasicAttributes("userpassword", newPasswd);
    	 	
    	String name = "uid=" + uid + "," + base;
   
    	logger.debug("LDAP URL=[" + ldapURL + "], ldapUser=[" + ldapUser + "]");
                logger.debug("uid=[" + uid + "], base=[" + base + "]");
        
                logger.debug("name do changePassword: " + name);
                logger.debug("DirContext.REPLACE_ATTRIBUTE : " + DirContext.REPLACE_ATTRIBUTE);
                logger.debug("attrs : " + attrs);
        
                ctx.modifyAttributes(name, DirContext.REPLACE_ATTRIBUTE, attrs);
        
                logger.debug("Finalizando o método changePassword ...");
                
    }

Todos os atributos estão chegando na classe corretamente, porém de este erro. Alguém tem aguma opinião?

Obrigado

Vlw

Olá!

A causa principal desse erro é tentar acessar um objeto informando nome errado.
O primeiro passo é verificar se o DN do objeto “user” (lá no LDAP) corresponde ao valor que você tem na variável name.

Informe pra gente se você já fez esse teste, ou então se tiver duvida sobre como fazer é só falar.

Como poderia verificar esta informação amigo?

Existe um arquivo “LDAP.properties”, onde está especificado da seguinte forma:

LDAP_URL=ldap://servidor.cgr.nome.com:389
LDAP_USER=cn=xxxx
LDAP_PASSWD=yyyy
LDAP_BASE=cn=users,dc=cgr,dc=nome,dc=com

No método, o cn é igual ao que está especificado no properties.

uid = ID do usuário no banco.

Vlw…

O cn do usuário está errado(no object), ou ele está em uma ‘ou’ diferente, ou ele não existe na base.

Se estiver utilizando Active Directory, não se esqueça que a senha tem de ser enviada em um canal criptografado e a senha deve ser um Unicode de 16bits.

Para resolver, tenho que mudar o valor cn da última linha do properties de cn=users para cn=xxxx … Certo amigo?

Para verificar o usuário na base é simples, basta usar qualquer client LDAP para acessar o diretório e procurar o item desejado. Depois peça para mostrar o DN (nome completo do objeto) e compare com a string “name” do seu programa…

Caso você não esteja habituado com esse procedimento, vou colocar passo-a-passo utilizando a ferramenta JXplorer:

  1. Baixar e instalar o JXplorer (http://sourceforge.net/projects/jxplorer)
  2. Abra o programa e clique em Conectar. Preencher os dados de conexão: Host do servidor, porta, e os dados de autenticação (se você não souber tente achar na sua aplicação, provavelmente ela usa esses dados ao conectar).
  3. Se tudo deu certo você vai visualizar o diretório do LDAP, ou seja, a árvore de objetos. Navegue até chegar os elementos usados na sua aplicação, procure os registros que representam os usuários do sistema.
  4. Quando encontrar o objeto, clique sobre ele com o botão direito e clique em “Copy DN”. Pronto, o caminho para o objeto no servidor foi copiado, vá até algum editor de texto e cole.
  5. Agora é só comparar com o que a sua aplicação está tentando modificar, é o valor da variável “name”.
  6. Se estiverem diferentes modifique o programa para acessar o objeto pelo endereço correto.

Boa sorte, qualquer coisa posta aí!

Tentei aqui e não consegui, coloquei os dados do arquivo properties no software e não conectou… vou verificar estas informações aqui com o pessoal… outra pergunta é a seguinte, o post que enviei antes do seu é coerente né?

Vlw…

Ele deveria conectar com aquelas informações que estão no arquivo .properties mesmo… da uma olhadinha aí, se precisar coloca o erro que está dando.

Eu acho que isso não vai funcionar porque são duas coisas diferente, o cn=xxxx é o objeto correspondente a um usuário, e o cn=users é o diretório base onde estão os objetos.

Mas continue seus testes aí, diga o que conseguir descobrir

[quote=IgorFranco]Boa tarde amigos,

Tenho uma aplicação que possui uma funcionalidade de troca de senha, onde troca a senha do LDAP com JNDI, mas está apresentando o erro abaixo quando tento trocar a senha.

Erro:

AlteraSenhaPortlet.changePassword: javax.naming.NameNotFoundException: object does not exist

Método:


    public void changePassword(String uid, String newPasswd) throws NamingException {
        
    	logger.debug("Iniciando o método changePassword ...");
    	System.out.println("newPasswd: " + newPasswd);
    	
    	BasicAttributes attrs = new BasicAttributes("userpassword", newPasswd);
    	 	
    	String name = "uid=" + uid + "," + base;
   
    	logger.debug("LDAP URL=[" + ldapURL + "], ldapUser=[" + ldapUser + "]");
                logger.debug("uid=[" + uid + "], base=[" + base + "]");
        
                logger.debug("name do changePassword: " + name);
                logger.debug("DirContext.REPLACE_ATTRIBUTE : " + DirContext.REPLACE_ATTRIBUTE);
                logger.debug("attrs : " + attrs);
        
                ctx.modifyAttributes(name, DirContext.REPLACE_ATTRIBUTE, attrs);
        
                logger.debug("Finalizando o método changePassword ...");
                
    }

Todos os atributos estão chegando na classe corretamente, porém de este erro. Alguém tem aguma opinião?

Obrigado

Vlw

[/quote]

Utilizei o método alterarAtributo para alterar a senha e o médoto hashMD5Password para encriptar a senha com md5. Segue os métodos abaixo.

alterarAtributoLdap("cnDoUsuario", "userPassword", ldap.hashMD5Password("novaSenhaDoUsuario"));
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;import com.sun.org.apache.xml.internal.security.utils.Base64;

	public String hashMD5Password(String password) {
		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			digest.update(password.getBytes("UTF8"));
			String md5Password = Base64.encode(digest.digest());
			return "{MD5}" + md5Password;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;

	public boolean alterarAtributoLdap(String cn, String atributo, String valor) {  
        Hashtable env = new Hashtable();  
  
        env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );  
        env.put( Context.PROVIDER_URL,            "ldap://ldap.uerr.lan:389" );  
        env.put( Context.SECURITY_AUTHENTICATION, "simple" );  
        env.put( Context.SECURITY_PRINCIPAL,      "cn=suporte,dc=uerr,dc=edu,dc=br" );  
        env.put( Context.SECURITY_CREDENTIALS,    "root@dvt1245" );  
         
        try {  
            DirContext dico = new InitialDirContext( env );  
            ModificationItem[] moit = { new ModificationItem( DirContext.REPLACE_ATTRIBUTE, new BasicAttribute( atributo, valor ) ) };
  
            dico.modifyAttributes( "cn="+ cn + ",ou=People,dc=uerr,dc=edu,dc=br", moit );  
            dico.close();  
              
            return true;  
        } catch ( Exception ae ) {  
            ae.printStackTrace();  
        }  
          
        return false;  
    }