Como fazer logout consistente em JSF?

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.

[code]

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
	
}

}[/code]

Página html.

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

Alguém poderia me ajudar?

Muito obrigado,

Att,
André Vieira.

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.

[quote=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.[/quote]

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.

[quote=Andr?de Souza Vieira][quote=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.[/quote]

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.

[/quote]

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.

[quote=thiago.correa][quote=Andr?de Souza Vieira][quote=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.[/quote]

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.

[/quote]

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.[/quote]

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.