Jsf filter não funciona da erro 500.

Java

15/09/2014

Eu estou tentando fazer um filter na minha aplicação para proteger as minhas páginas.

Está é minha página de login:

<div class="container-fluid">
	

        <div id="context" title="Acesso">
        <p:dialog header="Faça login" id="dialog" widgetVar="login" minHeight="400" minWidth="400"
        	modal="true" closable="false" position="center" showEffect="slide" draggable="true" resizable="true" visible="true" >
        <h:form id="login-form">
           <h:outputText value="Login:"/>
           <h:inputText value="#{loginBean.login}" id="username"/>
           <br/>
           <h:outputText value="Senha:"/>
           <h:inputSecret value="#{loginBean.senha}" id="password"/>
           <br/>
           <h:commandButton id="button" value="Login" action="#{loginBean.doLogin}"/>
           <br/>
           <h:commandLink action="#{navigationBean.redirectToInfo}" value="Info page"/>
           <br/>
           <h:messages />
           <br/>
        </h:form>
        </p:dialog>
        </div>


O método doLogin() do loginBean:

public String doLogin(){
		//Find user 
		try {String sqlQuery = "SELECT * FROM usuario"
				+ " WHERE login='"+this.login+"'"
				+ " and senha='"+this.senha+"' ; ";
		Query query = entityManager.createNativeQuery(sqlQuery, Usuario.class);
		usuario = (Usuario) query.getSingleResult();	  
		papel = usuario.getPapel().getId();
		
		
		
		enableButton();
		
		return navigationBean.redirectToWelcome();
		
		}catch ( NoResultException ne) {
			// Set login ERROR
	        FacesMessage msg = new FacesMessage("Erro de login!", "ERROR MSG");
	        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
	        FacesContext.getCurrentInstance().addMessage(null, msg);
	         
	        // To to login page
	        return navigationBean.toLogin();
		}
	}



No NavigationBean todos os redirecionamentos:

**
* Simple navigation bean
* @author 
*
*/
@ManagedBean
@SessionScoped
public class NavigationBean implements Serializable {

   private static final long serialVersionUID = 1520318172495977648L;

   /**
    * Redirect to login page.
    * @return Login page name.
    */
   public String redirectToLogin() {
       return "/login.xhtml?faces-redirect=true";
   }
    
   /**
    * Go to login page.
    * @return Login page name.
    */
   public String toLogin() {
       return "/login.xhtml";
   }
    
   /**
    * Redirect to info page.
    * @return Info page name.
    */
   public String redirectToInfo() {
       return "/info.xhtml?faces-redirect=true";
   }
    
   /**
    * Go to info page.
    * @return Info page name.
    */
   public String toInfo() {
       return "/info.xhtml";
   }
    
   /**
    * Redirect to welcome page.
    * @return Welcome page name.
    */
   public String redirectToWelcome() {
       return "/index.xhtml?faces-redirect=true";
   }
    
   /**
    * Go to welcome page.
    * @return Welcome page name.
    */
   public String toWelcome() {
       return "/index.xhtml";
   }
    
}


E a minha classe LoginFilter:

public class LoginFilter implements Filter {
 
    /**
     * Checks if user is logged in. If not it redirects to the login.xhtml page.
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Get the loginBean from session attribute
        LoginBean loginBean = (LoginBean)((HttpServletRequest)request).getSession().getAttribute("loginBean");
         
        // For the first application request there is no loginBean in the session so user needs to log in
        // For other requests loginBean is present but we need to check if user has logged in successfully
        if (loginBean == null || !loginBean.getLoggedIn()) {
            String contextPath = ((HttpServletRequest)request).getContextPath();
            ((HttpServletResponse)response).sendRedirect(contextPath + "/login.xhtml");
        }
         
        chain.doFilter(request, response);
             
    }
 
    public void init(FilterConfig config) throws ServletException {
        // Nothing to do here!
    }
 
    public void destroy() {
        // Nothing to do here!
    }  
     
}



Então configurei o meu web xml assim:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="3.0"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<display-name>my-app</display-name>
	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>
	<context-param>
		<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
		<param-value>true</param-value>
	</context-param>
	<mime-mapping>
		<extension>ico</extension>
		<mime-type>image/x-icon</mime-type>
	</mime-mapping>
	<context-param>
		<param-name>com.sun.faces.writeStateAtFormEnd</param-name>
		<param-value>false</param-value>
	</context-param>
	<error-page>
		<error-code>404</error-code>
		<location>/faces/error.xhtml</location>
	</error-page>
	<error-page>
		<error-code>500</error-code>
		<location>/faces/error.xhtml</location>
	</error-page>
	<!-- Login filter -->
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>br.com.myapp.filter.LoginFilter</filter-class>
    </filter>
 <!-- Set the login filter to secure all the pages of the application  -->
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
    <!-- By default go to secured welcome page -->
    <welcome-file-list>
        <welcome-file>/index.xhtml</welcome-file>
    </welcome-file-list>
 
    <!-- Staring JSF -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
    <!-- JSF URL mapping -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
  
</web-app>


Após a confirguração do web.xml quando acesso localhost:8080 não redireciona para o login.xhtml como antes e da erro 500 que a pagina login.xhrtml nao foi encontrada.
Cássia Freitas

Cássia Freitas

Curtidas 0

Respostas

Ronaldo Lanhellas

Ronaldo Lanhellas

15/09/2014

Passei por um problema parecido a algum tempo atrás, vamos lá. Creio que o problema esteja porque o chain.doFilter() está sendo executado incondicionalmente, então coloque um else e teste. Ficaria assim:

  // For the first application request there is no loginBean in the session so user needs to log in
        // For other requests loginBean is present but we need to check if user has logged in successfully
        if (loginBean == null || !loginBean.getLoggedIn()) {
            String contextPath = ((HttpServletRequest)request).getContextPath();
            ((HttpServletResponse)response).sendRedirect(contextPath + "/login.xhtml");
        }else{          
        chain.doFilter(request, response);
        }
GOSTEI 0
Cássia Freitas

Cássia Freitas

15/09/2014

Eu fiz isso e permaneceu o erro. Então coloquei breakpoints na minha classe LoginFilter e acessei o sistema em debug e notei que ele está em um loop no primeiro bloco if

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Get the loginBean from session attribute
        LoginBean loginBean = (LoginBean)((HttpServletRequest)request).getSession().getAttribute("loginBean");
         
        // For the first application request there is no loginBean in the session so user needs to log in
        // For other requests loginBean is present but we need to check if user has logged in successfully
        if (loginBean == null || !loginBean.getLoggedIn()) {
            String contextPath = ((HttpServletRequest)request).getContextPath();
            ((HttpServletResponse)response).sendRedirect(contextPath + "/login.xhtml");
        }else{
        	
        	chain.doFilter(request, response);
        }
         
        
             
    }



O loginBean vem null para que o usuário seja direcionado ao login.xhtml, mas não direciona e começa tudo de novo num loop infinito.
GOSTEI 0
Ronaldo Lanhellas

Ronaldo Lanhellas

15/09/2014

Certo. Possivelmente a causa do problema seja esta: A página login.xhtml está sendo interceptada pelo Filter, então vejamos o que ocorre:

1 - Você abre uma página qualquer chamada index.xhtml (que está sendo interceptada);
2 - O Filter é chamado e entra no if para direcionar para a página login.xhtml;
3 - A página login.xhtml também é interceptada (isso não deve acontecer) e o Filter é chamado denovo, entrando no IF e redirecionando para o login.xhtml;
4 - Repete o passo 3 eternamente.

Solução: Você pode colocar uma condição no seu doFilter() para checar se a página é a login.xhtml e caso seja você apenas manda continuar o fluxo com o chain.doFilter(), ou você pode mudar o seu filtro para que não intercepte o login.xhtml.
GOSTEI 0
POSTAR