Como fazer logout consistente em JSF?

4 respostas
A

Boa noite caros!

Não estou conseguindo fazer logout de uma aplicação com JSF. Ela redireciona para página de autenticação,
entretanto se acessar a pagina principal depois do logout ela permite o acesso sem pedir login de autenticação.

Para melhor entendimento, o código está abaixo:

public String logout()
	{
		/*
		FacesContext fc = FacesContext.getCurrentInstance();
		HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
		request.getSession().invalidate();*/
		// Esse acima também não deu certo...
		
		FacesContext fc = FacesContext.getCurrentInstance();
		ExternalContext ec = fc.getExternalContext();
		HttpSession session = (HttpSession)ec.getSession(false);
		session.removeAttribute(this.login);
		
		// Esse acima também não deu certo...
		
		return "autenticar";
	}
O filtro dinâmico funcional.
package filtro;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebFilter (servletNames={"Faces Servlet"})
public class controleDeAcesso implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest req = (HttpServletRequest) request;
		HttpSession session = req.getSession();
		
		if (session.getAttribute("usuario") != null ||
				req.getRequestURI().endsWith("autenticar.xhtml"))
		{
			chain.doFilter(request, response);
		}
		else
		{
			HttpServletResponse res = (HttpServletResponse) response;
			res.sendRedirect("autenticar.xhtml");
		}
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

}

Página html.

<h:outputLink value="logout" action="usuarioBean.logout">

Alguém poderia me ajudar?

Muito obrigado,

Att,
André Vieira.

4 Respostas

M

Opa! Eu estava passando agora mesmo por esse problema de logout, consegui resolver fazendo dessa forma:

FacesContext context = FacesContext.getCurrentInstance(); 
        context.getExternalContext().getSessionMap().remove("#{usuarioBean}");
        
        HttpSession session = (HttpSession)FacesContext.getCurrentInstance()
        					  .getExternalContext().getSession(true);
        		    session.invalidate();

onde tem #{usuarioBean}, é a referência ao meu bean com Session Scope que eu queria destruir. Até agora está funcionando, ainda estou aqui fazendo mais uns testes. Não sei se é a forma correta ou se há algo melhor para nós, espero que alguém possa responder.

A

Marcelo de Andrade:
Opa! Eu estava passando agora mesmo por esse problema de logout, consegui resolver fazendo dessa forma:

FacesContext context = FacesContext.getCurrentInstance(); 
        context.getExternalContext().getSessionMap().remove("#{usuarioBean}");
        
        HttpSession session = (HttpSession)FacesContext.getCurrentInstance()
        					  .getExternalContext().getSession(true);
        		    session.invalidate();

onde tem #{usuarioBean}, é a referência ao meu bean com Session Scope que eu queria destruir. Até agora está funcionando, ainda estou aqui fazendo mais uns testes. Não sei se é a forma correta ou se há algo melhor para nós, espero que alguém possa responder.

Aqui não deu assim também, engraçado que até com @viewscoped ele acessa…

tentei de todas as formas possíveis de acordo com meu pensamento, no entanto não consegui…

Muito obrigado pela ajuda!

Até mais.

T

Andr?de Souza Vieira:
Marcelo de Andrade:
Opa! Eu estava passando agora mesmo por esse problema de logout, consegui resolver fazendo dessa forma:

FacesContext context = FacesContext.getCurrentInstance(); 
        context.getExternalContext().getSessionMap().remove("#{usuarioBean}");
        
        HttpSession session = (HttpSession)FacesContext.getCurrentInstance()
        					  .getExternalContext().getSession(true);
        		    session.invalidate();

onde tem #{usuarioBean}, é a referência ao meu bean com Session Scope que eu queria destruir. Até agora está funcionando, ainda estou aqui fazendo mais uns testes. Não sei se é a forma correta ou se há algo melhor para nós, espero que alguém possa responder.

Aqui não deu assim também, engraçado que até com @viewscoped ele acessa…

tentei de todas as formas possíveis de acordo com meu pensamento, no entanto não consegui…

Muito obrigado pela ajuda!

Até mais.

Se substituir o true no getSession por false, não funciona?! O true cria uma nova sessão!
O ideal seria você ter um filter e verificar se existe um atributo na sessão, caso contrário você o redirecionaria para a tela de login.

A

thiago.correa:
Andr?de Souza Vieira:
Marcelo de Andrade:
Opa! Eu estava passando agora mesmo por esse problema de logout, consegui resolver fazendo dessa forma:

FacesContext context = FacesContext.getCurrentInstance(); 
        context.getExternalContext().getSessionMap().remove("#{usuarioBean}");
        
        HttpSession session = (HttpSession)FacesContext.getCurrentInstance()
        					  .getExternalContext().getSession(true);
        		    session.invalidate();

onde tem #{usuarioBean}, é a referência ao meu bean com Session Scope que eu queria destruir. Até agora está funcionando, ainda estou aqui fazendo mais uns testes. Não sei se é a forma correta ou se há algo melhor para nós, espero que alguém possa responder.

Aqui não deu assim também, engraçado que até com @viewscoped ele acessa…

tentei de todas as formas possíveis de acordo com meu pensamento, no entanto não consegui…

Muito obrigado pela ajuda!

Até mais.

Se substituir o true no getSession por false, não funciona?! O true cria uma nova sessão!
O ideal seria você ter um filter e verificar se existe um atributo na sessão, caso contrário você o redirecionaria para a tela de login.

Esse filtro existe, eu postei o código acima. O filtro faz essa função que você disse, acontece que clico no botão sair na página principal do sistema ele chama um método do bean logout e redireciona para autenticar, no entanto se colocar na url o endereço da página principal, o filtro não entra em ação, com isso deixa o usuário acessar a página principal.

Fiz um teste que deu um resultado interessante, no método do filtro coloquei um session.remove(“usuario”) logo após chain que acessa o sistema,
e ele pediu para efetuar login novamente no sistema.

public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest req = (HttpServletRequest) request;
		HttpSession session = req.getSession();
		
		if (session.getAttribute("usuario") != null ||
				req.getRequestURI().endsWith("autenticar.xhtml"))
		{
			chain.doFilter(request, response);
                        // coloquei essa linha para teste, e funcionou. 
                        session.removeAttribute("usuario");
		}
		else
		{
			HttpServletResponse res = (HttpServletResponse) response;
			res.sendRedirect("autenticar.xhtml");
		}
	}

Após pareceu vários questionamentos, será que o método logout no UsuarioBean não tem acesso?

O que faz essa notação @WebFilter (servletNames={“Faces Servlet”}) incluida no filtro? Ela pegas todas as requisições automaticamente?

Não posso incluir ela no UsuarioBean para ter acesso as requisições e implementar a interface publica Filter, e assim, implementar o método
logout semelhante ao método doFilter, mas adaptado para apenas remover a sessão do usuário?

Muito obrigado,

Att,

André Vieira.

Criado 15 de novembro de 2012
Ultima resposta 16 de nov. de 2012
Respostas 4
Participantes 3