Filtro sempre pega URL anterior e não atual

Olá,

Estou fazendo um sistema de segurança e preciso analisar todas as URLs requisitadas para decidir se libero ou não o acesso. Meu problema é que o filtro que criei está sempre retornando uma URL anterior… e não exatamente a que o usuário está requisitando.

Por exemplo:

  • Usuário clica no menu “Pesquisar grupo”
  • Meu filtro nesse momento recebe uma requisição para acessar “/restrito/index.xhtml”
  • Depois usuário clica no menu “Pesquisar função”
  • Meu filtro nesse momento recebe uma requisição para acessar “/restrito/cadastros/grupo/Search.xhtml”

Ou seja, meu filtro sempre recebe a requisição atrasada. Nunca sei o que exatamente o usuário quer acessar!

Eu pensei que pudesse ser alguma funcionalidade AJAX do Primefaces que estivesse fazendo isso, então desabilitei no menu o AJAX. Ficou assim:

<p:menuitem action="#{funcaoController.prepareSearch}" ajax="false" value="Pesquisar função" icon="/images/funcao-24x24.png"/>
<p:menuitem action="#{grupoController.prepareSearch}" ajax="false" value="Pesquisar grupo" icon="/images/grupo-24x24.png"/>

Reparem no ajax=“false”.

Então o que será que poderia estar causando esse atraso no meu filtro?

Segue meu web.xml se interessar:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>
    <filter>
        <filter-name>SecurityFilter</filter-name>
        <filter-class>com.empresa.filtros.SecurityFilter</filter-class>
        <init-param>
            <param-name>ID_SISTEMA</param-name>
            <param-value>1</param-value>
        </init-param>
        <init-param>
            <param-name>PREFIXO_URL</param-name>
            <param-value>/faces</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SecurityFilter</filter-name>
        <url-pattern>/faces/restrito/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>    
    <welcome-file-list>
        <welcome-file>faces/restrito/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Segue também o trecho do meu filtro que captura a URL:

	// verifica se usuario tem perfil para acessar url:
    protected boolean checarPermissaoURL(HttpServletRequest request) {
        // Remove do inicio da URL o nome da aplicacao (ex.: /APLICATIVO1/)
        String endereco = request.getRequestURI().replaceFirst(request.getContextPath(), "");
        // Remove do inicio da URL o prefixo padrao (ex.: /faces)
        endereco = endereco.replaceFirst(prefixoUrl, "");
        // Se estiver tentando acessar a raiz, permita:
        if(endereco.equals("/")){
            return true;
        }
        // Qualquer outro endereco que nao a raiz, precisa ser validado:
        while (endereco.length() > 0) {
            // teste: libere página "grupo" e bloqueie página "funcao" ja que ela nao ta cadastrada
			if(endereco.startsWith("/restrito/cadastros/grupo")){
				return true;
            }
        }
        return false; // se url nao estiver cadastrada, nega acesso
    }

Agradeço qualquer ajuda! :smiley:

Bem… você pode trocar esse filtro por um PhasesListener (seria o mais adequado para JSF), mas, caso você ainda prefira o Filtro…
JSF usa sempre requisições do tipo POST, o que não muda a URL para o usuário. Talvez se você colocar redirect nas navegações de páginas, seu filtro comece a funcionar melhor. Mas isso pode te dar problemas com requisições que manda algo na requestScope.

Fernando, conversei com um colega de trabalho e parece que o problema é mesmo com o JSF que está sempre uma URL atrasada no próprio navegador.

Eu só uso beans com sessionScope. Será que posso mudar para redirect então sem medo?

Mas o interessante era descobrir pq o JSF faz isso, deve ser por motivos de desempenho né? Será que não vou ter outros prejuízos na minha aplicação?

Grato!

No caso do PhaseListener, será que eu conseguiria pegar a URL verdadeira que o usuário está requisitando?

Sim PhaseListener pega a url que esta tentando ser acessada mesmo via POST