Julio Cezar Dourado Desenvolvedor Web

Construindo uma página com login no JSF

Neste post vou falar sobre um assunto um pouco trivial e que qualquer iniciante no framework JSF pode se perder: As fases do JSF e onde interceptar a navegação para que o usuário realize a autenticação.

É importante que você saiba o que é JSF e como configurá-lo em seu editor, aqui estarei utilizando o Eclipse, caso não saiba como configurar em seu editor, ao final, deixarei alguns links para lhe ajudar.

Vamos la =) .

Fases do JSF

O JSF funciona através de fases que são invocadas a partir do momento que abrimos uma página.

Então, o JSF executa um processo para coletar as informações, validar e criar a página de resposta que será enviada ao usuário.

Este processo é composto por 6 fases:

Fases do JSF

Restore View

Fase onde o JSF criará uma árvore de componentes, contendo um objeto para cada componente visual do formulário e, se for a primeira exibição da página, ele pula todas as fases e vai para a Render Response.

Se a página já foi exibida, o framework buscará pela árvore já existente.

Apply Request Values

Nesta fase, o framework pega os valores do formulário, eles são recebidos como Strings independente do tipo.

Process Validation

O JSF converte os valores existentes para os tipos que estão vinculados nas propriedades dos Managed Beans.

Após a conversão, é feita a validação desses valores.

Se ocorrer algum erro em qualquer dessas etapas, o JSF redireciona para a fase Render Response.

Update Model Values

Os dados convertidos são colocados nos objetos Managed Beans que estão vinculados.

Invoke Application

O método do atributo action que está vinculado a algum botão que foi acionado é avalido pela Expression Language e seu valor é retornado.

Render Reponse

O JSF processa a página recebida pelas fases anteriores e gera o código XHTML para o usuário.

Criação do Login

Primeiramente vamos criar nosso xhtml com os campos e botões para login vinculado com um Managed Bean e outro xhtml para ser a página inicial após o login do usuário.

A página deve ter os campos vinculados a um Managed Bean chamado usuário e um botão vinculado a algum método para logar.

Este foi meu código, claro, há diversos meios diferente para se fazer o mesmo:

Formulário de login XHTMl

E este foi o resultado:

Formulário de login XHTMl

No método logar vou verificar se o usuário e a senha correspondem ao meu nome: “Julio”.

Caso o usuário ou a senha forem diferentes de “Julio”, exibirei uma mensagem informando que o usuário é inválido.

Em outros casos será invocado um DAO que verificará se o usuário existe na base de dados ou o que for preciso.

Crie, também, uma página de resposta caso o usuário esteja correto.

Segue o código da classe Usuário:

Código da classe Usuário

E, também, o código do XHTML de resposta em caso de sucesso.

Código da página de resposta

Testes

Vamos testar nossa página:

Teste do login em sucesso

Primeiramente coloquei os campos de modo correto, ou seja, com os valores em “Julio”, e após pressionar o botão “Login” a página de sucesso foi retornada como esperado.

Teste do login em sucesso

Mas tem um problema, conseguimos acessarmos diretamente a página de sucesso, pois não há nenhuma validação se o usuário está logado. Em casos de sistemas grandes, isso pode ser um enorme problema, pois qualquer usuário poderia ter acesso a informações não permitidas.

Correção

Devemos criar um login que valide se o usuário já está no sistema, então vamos criar uma classe que sirva como ouvinte entre as fases do JSF.

Para isto, é preciso:

  • Criar uma classe que implemente a interface PhaseListener;
  • Registrar no faces-config.xml.

Criarei uma classe chamada “Listener” que implementa a interface PhaseListener.

Esta interface possui 3 métodos:

  • beforePhase: código que será executado antes do processamento da fase;
  • afterPhase: código que será executado após o processamento da fase;
  • getPhaseId: retorna um enum com o nome da fase atual.

Devemos implementar nosso método para verificar se o usuário está logado no método “afterPhase”.

Para verificar se a página que está sendo acessada é diferente da página “login.xhtml” devemos pegar a instância atual do “FacesContext” e, partir dele, pegar o ViewRoot e o ViewId que contém o nome da página atual:

Construção da interceptação da navegação

Após isto, é preciso verificar se o usuário está logado, isto pode ser feito com um atributo booleano na classe Usuario ou verificar se os parametros estão de acordo com o que queremos, vou utilizar esta segunda opção.

Para pegar o objeto Usuario que queremos, devemos utilizar o objeto “Application” a partir do FacesContext atual, através do método “getApplication”.

Então utilizamos o método “evaluateExpressionGet” do objeto “Application”:

Conseguindo o objeto a partir da Application

Agora aplicamos nossa validação, no meu caso apenas peguei o atributo usuario a partir do objeto Usuario atual e verifiquei se é diferente de “Julio”, se for, retorno a navegação para a página login.

Isto é feito a partir do objeto “NavigationHandler” conseguido a através do objeto “Application” e invoco o método “handleNavigation”, que altera o fluxo. Por último chamo o método “renderResponse” do FacesContext.

E, claro, devemos indicar ao Listener qual fase que desejamos interceptar, que no nosso caso é a “Restore View” indicando no método “getPhaseId”.

Resultado final

Para que funcione, precisamos registrar no faces-config.xml que ele é um Listener.

Registrando o Listener no faces-config

Agora ao tentarmos entrar na página de sucesso diretamente, ele não vai.

Resultado final

Para quem deseja obter a URL correta, apenas adicionar “?faces-redirect=true” ao final da String de redirecionamento no Listener:

Parâmetro de navegação alterado

Então:

Entrada no browser

Retorna:

Resposta no browser

Obtendo o resultado desejado.

Comente em caso de dúvidas ou falhas =D.

Obrigado!!

Segue alguns links de artigos e alguns livros que ajudam nessa caminhada:

JSF - Criando um módulo de login

Java WEB criando uma tela de login com JPA e JSF

JSF - Criando uma tela de login

Livro: JSF Eficaz - Casa do Código.