Phaselistener: alguém conhece bem pra poder tirar essa dúvida?

7 respostas
Kleber-rr

Olá pessoal, estou tendo dificuldades na implementação do PhaseListener para a validação do usuario na sessão. O problema é o seguinte: No meu sistema de login, o usuario acessa o sistema, no qual tem abas chamando outras paginas jsp que acessam informações em um banco de dados. O problema, é que, com a implementação do PhaseListener, o usuario loga direitinho, mas só tem acesso a pagina principal. Quando ele tenta acessar ou gravar alguma informação no banco, ou tenta abrir uma outra jsp a partir dessa principal, ele dá um reload no filtro (PhaseListener) e volta a tela de login.

Alguem pode me ajudar?? A dias eu estudo sobre isso e ainda não achei uma solução. Agradeço a ajuda. Segue meu PhaseListener:
public class AuthorizationListener implements PhaseListener {

   /**
    * 
    */
   private static final long serialVersionUID = 1L;

   public void beforePhase(PhaseEvent event) {

   }

   public void afterPhase(PhaseEvent event) {
      System.out.println("<-----------VALIDANDO REQUISIÇÃO------------>");

      FacesContext facesContext = event.getFacesContext();
      String currentPage = facesContext.getViewRoot().getViewId();

      boolean isLoginPage = (currentPage.lastIndexOf("login.jsp") > -1);
      HttpSession session = (HttpSession) facesContext.getExternalContext()
            .getSession(true);
      System.out.println("=======validado a página=======");
      Usuario currentUser = (Usuario) session.getAttribute("currentUser");

      if (!isLoginPage && currentUser == null) {
         NavigationHandler nh = facesContext.getApplication()
               .getNavigationHandler();
         System.out.println("<-------condicao lançada-------->");
         nh.handleNavigation(facesContext, null, "loginPage");
         System.out.println("<-------usuario nao logado-------->");
      }
   }

   public PhaseId getPhaseId() {
      return PhaseId.RESTORE_VIEW;
   }

}

7 Respostas

J

Cara,

tenho um código muito parecido com esse e funciona normalmente, mas gostaria de fazer uma observação:

no login vc tá incluindo o usuário na sessão com o nome de “currentUser”?

pois vc tá recuperando ele na linha:

Usuario currentUser = (Usuario) session.getAttribute("currentUser");

e logo abaixo faz o teste pra saber se a variável é null.

luizrobertofreitas

Amigo, estive dando uma olhada no seu código e notei que está utilizando o getExternalContext().getSession(true) com o parametro boolean, este parametro, conforme o link http://java.sun.com/javaee/5/docs/api/javax/faces/context/ExternalContext.html diz que uma nova sessão é criada caso não haja. Acredito que ele esteja criando uma nova sessão na chamada do método getSession(true).

Se vc resolver, retorna ai pra gente.

Inté

Kleber-rr
Junior Rufino:
Cara,

tenho um código muito parecido com esse e funciona normalmente, mas gostaria de fazer uma observação:

no login vc tá incluindo o usuário na sessão com o nome de "currentUser"?

pois vc tá recuperando ele na linha:

Usuario currentUser = (Usuario) session.getAttribute("currentUser");

e logo abaixo faz o teste pra saber se a variável é null.

Meu HibernateSessionFilter está assim:
public class HibernateSessionFilter implements Filter {

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc)
			throws IOException, ServletException {

		HibernateUtil.openSession();
		try {
			HibernateUtil.currentSession().beginTransaction();
			fc.doFilter(req, res);
			HibernateUtil.currentSession().getTransaction().commit();
		} catch (Exception e) {
			throw new ServletException(e);
		} finally {
			HibernateUtil.closeCurrentSession();
		}
	}

	public void init(FilterConfig c) {
	}

	public void destroy() {
	}

}

Em que parte eu tenho que criar um atributo para sessão?? Como ficaria??

bronx

Kleber-rr,
Fiz uma parada assim há umas semanas.
No meu caso, eu criei um ManagedBean session-scoped que contém o usuário logado.
Eu faço o lookup desse bean e verifico se o meu Usuário está carregado, ou seja, se está logado.
Ficou +/- assim:

package br.com.bronx.myproject.handler;

import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.faces.context.FacesContext;

import br.com.bronx.myproject.dao.UsuarioDao;
import br.com.bronx.myproject.entidades.Usuario;
import br.com.bronx.myproject.tinytypes.Email;
import br.com.bronx.myproject.tinytypes.Senha;
import br.com.bronx.myproject.util.HibernateUtil;

public class LoginHandler {
	
	private Usuario usuario = new Usuario();
	private Boolean logado = new Boolean(false);
	
	public Usuario getUsuario() {
		return usuario;
	}
	
	public Boolean isLogado() {
		return this.logado;
	}
	
	public void setLogado(Boolean logado) {
		this.logado = logado;
	}
	
	public String logar() throws NoSuchAlgorithmException{
		String outcome = "login";
		if (!(this.usuario.getEmail().isEmpty() || this.usuario.getSenha().isEmpty())){
			UsuarioDao usuarioDao = new UsuarioDao(HibernateUtil.currentSession());
			Usuario usuario = usuarioDao.getUsuario(new Email(this.usuario.getEmail()), new Senha(this.usuario.getSenha()));
			if (usuario != null){
				this.usuario = usuario;
				this.logado = true;
				Calendar calendar = new GregorianCalendar();
				Date dataHoraAtual = new Date();
				calendar.setTime(dataHoraAtual);
				this.usuario.setDataUltimoAcesso(calendar);
				usuarioDao.update(this.usuario);
				outcome = "menu";
			} 
		}
		return outcome;
	}
	
	public String logout(){
		this.logado = false;
		this.usuario = new Usuario();
		return "login";
	}
	
	public static LoginHandler getCurrentLoginHandler(){
		FacesContext facesContext = FacesContext.getCurrentInstance();
		ELContext elContext = facesContext.getELContext();
		ELResolver elResolver = facesContext.getApplication().getELResolver();
		LoginHandler loginHandler = (LoginHandler)elResolver.getValue(elContext, null, "loginHandler");
		return loginHandler;
	}

}

No Listener, coloque algo como:

public void afterPhase(PhaseEvent event){
	        FacesContext facesContext = event.getFacesContext();
                String loginPage = "/Login.jsp";
                String requestedPage = facesContext.getViewRoot().getViewId();
		Usuario usuario = LoginHandler.getCurrentLoginHandler().getUsuario();
                if ((usuario == null || !usuario.isLogado()) && !(paginaRequisitada.lastIndexOf(loginPage) > -1)){
                        NavigationHandler navHandler = facesContext.getApplication().getNavigationHandler();
			navHandler.handleNavigation(facesContext, null, "login");
		}
	}

Lembre-se de colocar a Nav-rule:

<navigation-rule>
		<from-view-id>*</from-view-id>
		<navigation-case>
			<from-outcome>login</from-outcome>
			<to-view-id>/Login.jsp</to-view-id>
			<redirect/>
		</navigation-case>
	</navigation-rule>

Isso tudo falando superficialmente…
No meu caso ainda tenho diversos agravantes, como controle de permissões (“usuário x não pode acessar página y”) e outros detalhes, como por exemplo as requisições feitas pelos componentes do richfaces.
Mas a idéia é essa!

Kleber-rr

bronx:
Kleber-rr,
Fiz uma parada assim há umas semanas.
No meu caso, eu criei um ManagedBean session-scoped que contém o usuário logado.
Eu fiço o lookup desse bean e verifico se o meu Usuário está carregado, ou seja, se está logado.
Ficou +/- assim:

package br.com.bronx.myproject.handler;

import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.faces.context.FacesContext;

import br.com.bronx.myproject.dao.UsuarioDao;
import br.com.bronx.myproject.entidades.Usuario;
import br.com.bronx.myproject.tinytypes.Email;
import br.com.bronx.myproject.tinytypes.Senha;
import br.com.bronx.myproject.util.HibernateUtil;

public class LoginHandler {
	
	private Usuario usuario = new Usuario();
	private Boolean logado = new Boolean(false);
	
	public Usuario getUsuario() {
		return usuario;
	}
	
	public Boolean isLogado() {
		return this.logado;
	}
	
	public void setLogado(Boolean logado) {
		this.logado = logado;
	}
	
	public String logar() throws NoSuchAlgorithmException{
		String outcome = "login";
		if (!(this.usuario.getEmail().isEmpty() || this.usuario.getSenha().isEmpty())){
			UsuarioDao usuarioDao = new UsuarioDao(HibernateUtil.currentSession());
			Usuario usuario = usuarioDao.getUsuario(new Email(this.usuario.getEmail()), new Senha(this.usuario.getSenha()));
			if (usuario != null){
				this.usuario = usuario;
				this.logado = true;
				Calendar calendar = new GregorianCalendar();
				Date dataHoraAtual = new Date();
				calendar.setTime(dataHoraAtual);
				this.usuario.setDataUltimoAcesso(calendar);
				usuarioDao.update(this.usuario);
				outcome = "menu";
			} 
		}
		return outcome;
	}
	
	public String logout(){
		this.logado = false;
		this.usuario = new Usuario();
		return "login";
	}
	
	public static LoginHandler getCurrentLoginHandler(){
		FacesContext facesContext = FacesContext.getCurrentInstance();
		ELContext elContext = facesContext.getELContext();
		ELResolver elResolver = facesContext.getApplication().getELResolver();
		LoginHandler loginHandler = (LoginHandler)elResolver.getValue(elContext, null, "loginHandler");
		return loginHandler;
	}

}

No Listener, coloque algo como:

public void afterPhase(PhaseEvent event){
	        FacesContext facesContext = event.getFacesContext();
                String loginPage = "/Login.jsp";
                String requestedPage = facesContext.getViewRoot().getViewId();
		Usuario usuario = LoginHandler.getCurrentLoginHandler().getUsuario();
                if ((usuario == null || !usuario.isLogado()) && !(paginaRequisitada.lastIndexOf(loginPage) > -1)){
                        NavigationHandler navHandler = facesContext.getApplication().getNavigationHandler();
			navHandler.handleNavigation(facesContext, null, "login");
		}
	}

Lembre-se de colocar a Nav-rule:

<navigation-rule>
		<from-view-id>*</from-view-id>
		<navigation-case>
			<from-outcome>login</from-outcome>
			<to-view-id>/Login.jsp</to-view-id>
			<redirect/>
		</navigation-case>
	</navigation-rule>

Isso tudo falando superficialmente…
No meu caso ainda tenho diversos agravantes, como controle de permissões (“usuário x não pode acessar página y”) e outros detalhes, como por exemplo as requisições feitas pelos componentes do richfaces.
Mas a idéia é essa!


Blz man, vou testar e te falo. Agradeço por ter postado isso, pois é muito dificil os veteranos do GUJ ajudarem nesse assunto. Valeu.

bronx

Vish…
Eu que sou novo aqui sei muito bem o que é isso! :frowning:
Mas…tamo ae! :smiley:

Kleber-rr
bronx:
Vish... Eu que sou novo aqui sei muito bem o que é isso! :( Mas...tamo ae! :D
Eae man, Minha classe LoginHandler está assim:
public class LoginHandler {

	private LoginDAO loginDAO = new LoginDAO();

	/** Creates a new instance of ControleLogin */
	public LoginHandler() {

	}

	private Login LO = new Login();

	// 
	public Login getLO() {
		return LO;
	}

	public void setLO(Login LO) {
		this.LO = LO;
	}

	public String login() {
		System.out.println("login= " + LO.getLogin());
		System.out.println("senha= " + LO.getSenha());

		boolean ok = loginDAO.getCheca(LO.getLogin(), LO.getSenha(), "1");
		if (ok == true) {
			System.out.println("USUARIO LOGADO COM SUCESSO");
			return "ok";

		}
		boolean admin = loginDAO.getCheca(LO.getLogin(), LO.getSenha(), "2");
		if (admin == true) {
			System.out.println("ADMIN LOGADO COM SUCESSO");
			return "admin";
		} else
			System.out.println("ACESSO INVÁLIDO");
		return "erro";
	}

	public List<Usuario> getUsuarios() {
		System.out.println("carregando usuarios ...");
		Session session = HibernateUtil.currentSession();
		Dao<Usuario> dao = new Dao<Usuario>(session, Usuario.class);
		return dao.list();
	}

}

Você acha q eu posso implementar essa alteração sem problemas??

Criado 9 de setembro de 2009
Ultima resposta 10 de set. de 2009
Respostas 7
Participantes 4