JSF: Erro ao recuperar session [RESOLVIDO]

Olá pessoal :smiley:

Estou tentando implementar um controle de acesso na minha aplicação em JSF, para isso criei um Servlet Filter, porém a minha sessão não chega até lá…

//UsuarioMB.java public String logar() { FacesUtil.setSessionMapValue("userSession", this.usuario); return "success"; }
Este método acima (reduzido só para entendimento), registra apenas a sessão do bean Usuario, que fora instanciado nesta classe (UsuarioMB.java).

[code]//FacesUtil.java
public class FacesUtil
{
// remove objeto da sessao
public static void removeSessionMapValue(String key) {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(key);
}

	// Getters -----------------------------------------------------------------------------------
	public static Object getRequestMapValue(String key) {
    	return FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(key);
	}

	// Setters -----------------------------------------------------------------------------------
	public static void setRequestMapValue(String key, Object value) {
        FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(key, value);
	}
	// Getters -----------------------------------------------------------------------------------
	public static Object getSessionMapValue(String key) {
    	return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);
	}

	// Setters -----------------------------------------------------------------------------------
	public static void setSessionMapValue(String key, Object value) {
    	FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(key, value);
	} 

}[/code]

A partir dos métodos do FacesUtil acima, eu deveria manipular a sessão desejada.
No próprio UsuarioMB.java eu tenho um método que verifica se a sessão existe.

//UsuarioMB.java public boolean verifySession() { Usuario u = (Usuario)FacesUtil.getSessionMapValue("userSession"); if(u != null) return true; else return false; }

E por último, meu Filter…

[code]//SecutiryFilter.java
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
HttpServletResponse resp = (HttpServletResponse)response;

UsuarioMB u = new UsuarioMB();
if(u.verifySession()) chain.doFilter(request, response);
else resp.sendRedirect("/login.xhtml");

}[/code]

Quando eu rodo a aplicação dá NullPointerException, justamente na linha onde eu tento recuperar a sessão, como se ela não existisse. Porém no momento que o método logar é executado, eu fiz um teste e imprimi o conteúdo da sessão userSession logo após ter registrado ela, e funcionou na boa, então eu sei que ela existe.

Por que será que não consigo recuperá-la? Alguém já passou por isso?

Se alguém tiver alguma outra sugestão de fazer esse controle de acesso em JSF também será muito útil :smiley:

Pessoal,

Consegui resolver da seguinta forma:

  • Mudei meu filter:

[code]HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;

Usuario u = (Usuario)req.getSession().getAttribute(“userSession”);

if(u != null)
{
chain.doFilter(request, response);
}
else
{
resp.sendRedirect("/login.xhtml");
}[/code]

Descartando assim, o método verifySession do UsuarioMB.
Não sei se é a maneira mais correta mas foi a única que funcionou após muito tempo quebrando a cabeça. :smiley:

Fica aí minha solução, mas caso alguém saiba uma maneira melhor de implementar esse controle, fiquem a vontade e agradeço :smiley:

valeu Pessoal.

felipempantoja Bom dia !

          Estou tentando fazer esse controle de acesso, no meu caso vai ter vários tipos de usuários com varios tiṕos de acesso ! o que você recomenda ?

[quote=juniorsatanas]felipempantoja Bom dia !

          Estou tentando fazer esse controle de acesso, no meu caso vai ter vários tipos de usuários com varios tiṕos de acesso ! o que você recomenda ?[/quote]

Fala Junior, blz?
Cara, depois de tanto bater cabeça, tentar controlar acesso via ServletFilter, deopis via PhaseListener do JSF, agora achei uma solução muito mais robusta e flexivel: Spring Security.

Já ouviu falar? Dá uma olhada na documentação, é muito simples: http://static.springsource.org/spring-security/site/docs/2.0.x/reference/springsecurity.html

Eu tentei ajudar um cara num post aqui no guj mesmo, sobre a utilização do Spring Security, dá uma olhada: http://www.guj.com.br/posts/list/131765.java

Qualquer coisa é só falar cara…

Abraços.

felipempantoja estou usando JSF. como ficaria ? tenho que usar jsf + spring ?

No fim das contas vc ia ter que usar o spring sim. Tem um exemplo bom também nesse link: http://ocpsoft.com/java/acegi-spring-security-jsf-login-page/

Se quiser fazer alguma coisa bem simples cara, e como vc tá usando JSF, eu sugiro criar um PhaseListener ao invés de um ServletFilter. Aí vc pode interceptar uma requisição em todas as fases do ciclo de vida do JSF, vale a pena.

No PhaseListener, vc faria algo mais ou menos assim:

[code]public class AuthenticationPhaseListener implements PhaseListener {

public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW; //Só é executado na fase Restore View (a primeira)
}

public void afterPhase(PhaseEvent event) {
}

public void beforePhase(PhaseEvent event) {
    FacesContext fc = event.getFacesContext();

    NavigationHandler nh = fc.getApplication().getNavigationHandler();
    
    User userSesion = (User) fc.getExternalContext().getSessionMap().get("userSession");//Pega o seu usuário da sessão (o que está logado).
    
    String currentPage = fc.getViewRoot().getViewId();//Pega a pagina que o usuario esta tentando acessar
    if(currentPage.contains("admin/")) { //Digamos que suas paginas de acesso ADMIN estão dentro da pasta "admin"
            if(!userSession.getRole().equals("ADMIN")) {//Digamos que vc tenha uma String dizendo a permissao do usuario logado, se não for ADMIN...
                  nh.handleNavigation(fc, null, "login");//Redireciona pra tela de login (String "login" mapeada no faces-config)
            }
    }      
}

}[/code]

Tem que fazer o mapeamento desse phaseListener no seu faces-config:

<lifecycle> <phase-listener>br.com.app.controller.lifecycle.AuthenticationPhaseListener</phase-listener> </lifecycle>

Claro que isso é um exemplo bem básico, mas dá pra ir brincando, criando as suas regras de controle de acesso…
Qualquer coisa só postar… Valeu!

ok valeu !