Archive for the ‘Java’ Category

Usando criptografia no cadastro de usuários

Saturday, November 13th, 2010

O aplicativo desenvolvido no livro trabalha inteiramente com a senha do usuário aberta. Porém no tópico 6.8.2 damos uma dica de como configurar o Spring Security para trabalhar com a senha criptografada em MD5. O problema é que esta configuração não é suficiente para que o sistema inteiro trabalhe com a senha criptografada. Foi ai que o leitor Rafael Freitas entrou em contato e solicitou que fizessemos um post explicando como fazer esta alteração, o que faz todo o sentido.

Primeiro uma definição importante: a conhecido algoritmo Base64 na verdade é uma codificação e não criptografia, pois ele é reversível.  Para ser considerada uma criptografia o algoritmo tem que ser inversível, o algoritmo MD5 tem esta capacidade.

De maneira macro, para que o sistema trabalhe com a senha do usuário criptografada algumas alterações são necessárias:

  1. Configuração do framework de segurança para trabalhar com a senha criptografada (já realizado no tópico 6.8.2).
  2. Decidir onde realizar a encriptação da senha do usuário
  3. Encriptar a senha do usuário
  4. Não exibir a senha criptografada em tela ao editar um usuário

Veremos agora o entendimento de cada alteração e depois a alteração passo a passo.

2 Decidir onde realizar a encriptação da senha do usuário

Seguindo o método utilizado no livro de sempre analisar e argumentar bem em qual camada uma alteração deve ser feita, vamos pensar sobre a alteração da senha criptografada.

A camada de acesso a dados (UsuarioDAO) deve ser imediatamente descartada, pois como já foi explicado esta camada apenas transfere dados do sistema para o banco de dados, não deve fazer qualquer alteração ou transformação.

A camada de regra de negócio (UsuarioRN) é uma forte candidata, mas como a senha do usuário será criptografada e esta criptografia é irreversível significa que a senha do usuário entrará nela aberta  (ao salvar) e sairá criptografada (ao consultar). Acredito que isto pode causar alguma confusão. O ideal é que esta camada sempre trabalhe com a senha em um formato único.

Desta forma, a camada de visualização é o local correto para fazer a alteração e controlar a criptografia. Ela obrigatoriamente irá trabalhar com a senha aberta, pois é o que o usuário digita na tela, mas assim que receber esta senha deverá encriptar e enviar adiante para salvar, o que garante uma maior segurança.

3 Encriptar a senha do usuário

A encriptação da senha do usuário pode ser feita com uma classe do próprio Spring Security, conforme o exemplo a seguir:

import org.springframework.util.DigestUtils;

String senhaAberta = “teste123″;
String senhaCripto;
senhaCripto = DigestUtils.md5DigestAsHex(senhaAberta.getBytes());
System.out.println(senhaCripto);

Resultado

aa1bf4646de67fd9086cf6c79007026c

4 Não exibir a senha criptografada em tela ao editar um usuário

A partir do momento que o sistema começar a trabalhar com a senha criptografada não vai mais fazer sentido enviar esta senha para a tela, para alteração, como já é atualmente.

Não faz sentido pois pode causa confusão por dois motivos:

  • A senha em MD5 é bem maior que a senha real digitada. Se o usuário digitar uma senha de 5 caracteres, em MD5 ela terá 32 caracteres. Se ao alterar um registro o usuário perceber esta senha bem maior vai estranhar e vai achar que está errado.
  • Enviar a senha criptografada para a tela fará com que o campo de senha as vezes tenha uma senha aberta e outras vezes uma senha criptografada, com certeza é confuso.

Ou seja, se for o cadastro de um novo usuário a senha será preenchida normalmente, ser for uma alteração de usuário o campo senha deverá ser mantido em branco e o usuário somente preencherá este campo de quiser alterar a senha, senão deixa em branco.

Com isso definimos um comportamento do sistema: o campo de senha só será preenchido com senha aberta.

Porém se a senha for deixada em branco (significando que o usuário quer manter a senha antiga), como vamos salvar o registro do usuário se esta senha está em branco?

O segredo aqui é guardar a senha criptografada do usuário em outro local, quando a tela for aberta para edição (veremos como fazer no passo a passo).

Para manter o campo da senha em branco e considerar que ele só será preenchido quando o usuário quiser alterar existem duas opções:

1. Colocar um aviso junto ao campo dizendo: Preencher somente se quiser alterar.

2. Usar o componente do Primefaces WaterMark, que mostrará a mesma mensagem anterior, só que dentro do campo. http://www.primefaces.org/showcase/ui/watermark.jsf

Fazendo a alteração passo a passo

1. Crie uma nova propriedade String senhaCriptografada na classe UsuarioBean, gerando os métodos get e set.

2. Altere os campos de senha de tela para não serem obrigatórios caso seja uma edição de usuário. É possível identificar isto alterando o atributo  required dos campo Senha e Confirmar Senha para:
required=”#{empty contextoBean.usuarioLogado}”

3. Altere os campos de senha da tela para não re-exibirem a senha, configurando o atributo redisplay=”false”.

4. Altere o método editar() para armazenar a senha atual na propriedade senhaCriptograda.

5. Altere o método salvar() para recuperar a senhaCriptografada (senha = senhaCriptografada) caso esta não senha sido preenchida em tela, e para criptografar a senha caso tenha sido preenchida em tela.

6. Inclua na tela usuario.xhtml um campo inputHidden armazenando a senhaCriptografada:
<h:inputHidden value=”#{usuarioBean.senhaCriptografada}”/>
A classe UsuarioBean (métodos editar e salvar) ficará conforme o exemplo a seguir:

public String editar() {
    this.senhaCriptografada = this.usuario.getSenha();
    return "/publico/usuario";
}

public String salvar() {
	FacesContext context = FacesContext.getCurrentInstance();

	String senha = this.usuario.getSenha();
	if (senha != null &&
            senha.trim().length() > 0  &&
            !senha.equals(this.confirmarSenha)) {
		FacesMessage facesMessage = new FacesMessage("A senha não foi confirmada corretamente");
		context.addMessage(null, facesMessage);
		return null;
	}
	
	if (senha != null && senha.trim().length() == 0) {
		this.usuario.setSenha(this.senhaCriptografada);
	} else {
		String senhaCripto = DigestUtils.md5DigestAsHex(senha.getBytes());
		this.usuario.setSenha(senhaCripto);
	}

	UsuarioRN usuarioRN = new UsuarioRN();
	usuarioRN.salvar(this.usuario);
	[...]
}

Code Completion para XHTML no Eclipse

Thursday, October 21st, 2010

Recentemente foi liberada a melhoria no Eclipse que permite a utilização de code completion (assistente de código) para arquivos XHTML. Para quem trabalha bastante com JavaServer Faces ou Facelets isto é uma grande ajuda.  Este recurso foi liberado no dia 17/03/2010, ou seja, somente a versão Helios do Eclipse possui este recurso.

Para habilitar o code completion basta criar um Dynamic Web Project e na aba Configuration clicar em Modify. Na janela que se abrir selecione o facet JavaServer Faces como 2.0 e clique em OK. Neste momento não será mais possível clicar em Finish na tela de criação do projeto mas apenas em Next. Nas telas seguintes serão configuradas as JSF Capabilities que configuram as bibliotecas do JSF e configurações no aplicativo web.

Em JSFCapabilities é possível pré-configurar o JSF, informando a localização da biblioteca e o mapeamento que será considerado (o padrão é /faces/*). Clique em Finish.

Depois disso já será possível utilizar o code completion a partir de arquivos XHTML.

Este recurso já é abordado no tópico 1.4.4 do livro Programação Java para a Web (www.javaparaweb.com.br), onde é ensinada toda a preparação do ambiente de desenvolvimento para JavaServer Faces, PrimeFaces, Hibernate, Eclipse e MySQL.

Décio Heinzelmann Luckow

Lançamento do livro: Programação Java para a Web

Thursday, October 7th, 2010

Está lançado oficialmente o livro Programação Java para a Web, pela editora Novatec.

Programação Java para a Web é um livro inovador, com enfoque extremamente prático, que mostra passo a passo como desenvolver uma aplicação web utilizando a linguagem Java e as tecnologias mais poderosas e populares no arsenal dos desenvolvedores, como JavaServer Faces e Hibernate.

A metodologia do aprendizado é baseada no projeto de uma aplicação financeira pessoal completa, do início ao fim, em que serão abordadas várias técnicas de desenvolvimento em cada etapa do projeto, desde as mais tradicionais e conhecidas até as mais modernas, utilizando Web 2.0. Tudo isso sem abrir mão de uma arquitetura bem-definida e baseada no modelo MVC.

O livro ainda aborda:

- Preparação do ambiente de desenvolvimento
- Desenvolvimento Web usando JavaServer Faces com Ajax e PrimeFaces
- Gravação e consulta em banco de dados usando Hibernate
- Segurança de acesso e controle de usuários com Spring Security
- Estilos com CSS e uso de templates
- Envio de e-mail e integração com o Google Gmail
- Construção de relatórios com iReports e JasperReports
- Integração com o Yahoo! Finance para obtenção de gráficos e cotação de ações da Bovespa
- Como tornar sua aplicação multi-idiomas
- Modelagem e uso de web services
- Geração de gráficos

Clique aqui para saber onde comprar o seu exemplar.