Estou desenvolvendo uma aplicação web onde eu uso JSF + Facelets + RichFaces e preciso controlar quais paginas um usuário possui acesso e além disso dentro de uma pagina quais os componentes da tela o usuario pode ver, por exemplo um usuario operacional pode entrar na tela de pedidos e ver a lista de pedidos e detalhar algum desses pedidos, mas o usuario administrativo pode criar um novo pedido, excluir um pedido existente, etc., ou seja, quero deixar visivel na pagina apenas o que o perfil do usuario pode ver.
Pesquisei na internet e utilizando faces eu vi que posso criar PhaseListener e antes da fase de RENDER_RESPONSE eu posso pegar o viewRoot e setar o rendered dos componentes para false, dessa forma ele não aparece na tela.
Também é possivel sobrescrever cada componente da tela e dentro do meu novo componente posso colocar o controle se mostro ou não o componente na tela, mas acho que dessa forma da mais trabalho.
Gostaria de saber se alguém ja fez algo parecido com isso e qual solução utilizou ?
O valor que currentPage assume é o valor = “\home.jsp”, óbvio pois é de home que eu faço a requisição pelos menus para entrar nas telas do sistema.
Gostaria de saber como faço para para pegar o valor seguinte à home, por exemplo pegar “cadastro.jsp”, pois esse sim deve ter acesso restrito.
Se puder ajudar agradeço…
R
rsakurai
Oi dahenz,
Você só sabe qual página que será redirecionado depois que o ciclo de vida da requisição do faces passar pela fase INVOKE_APPLICATION.
Mas se você quer alterar a estrutura da arvore através do getViewId() para dar os rendered(false) nos componentes que não deve aparecer, você não vai conseguir, porque antes da fase RENDER_RESPONSE vc ainda não tem a estrutura da pagina que será exibida, e depois da fase RENDER_RESPONSE todas as alterações que você fizer não vão para a tela.
D
dahenz
Valew rsakurai!!!
Só tenho mais uma dúvida, eu consigo pelo menos bloquear o acesso à página antes do RENDER_RESPONSE???
Se consigo… onde faço isso??? Obrigado pela ajuda…
R
rsakurai
Cria um PhaseListener, nele vc sobrescreve o método beforePhase() para a fase RENDER_RESPONSE e pega a pagina que ele esta querendo acessar, depois vc verifica se ele pode ou não ter esse acesso, caso ele não possa faz um redirect para alguma pagina de erro.
K
Kleber-rr
Alguem aqui conseguiu utilizar o PhaseListener?? Funcionou direitinho??
Na minha aplicação, depois que eu logo, se eu tentar acessar o banco postgres, tentar salvar algo no banco ou abrir outra jsp ele me joga na tela de login novamente. Alguem sabe me dizer o que é que está acontecendo??
Minha classe AuthorizationListener:
packagebr.gov.rr.setrabes.util;importjavax.faces.application.NavigationHandler;importjavax.faces.context.FacesContext;importjavax.faces.event.PhaseEvent;importjavax.faces.event.PhaseId;importjavax.faces.event.PhaseListener;importjavax.servlet.http.HttpSession;importbr.gov.rr.setrabes.estrutura.Usuario;publicclassAuthorizationListenerimplementsPhaseListener{privatestaticfinallongserialVersionUID=1L;publicvoidafterPhase(PhaseEventevent){System.out.println(event.getPhaseId());FacesContextfacesContext=event.getFacesContext();StringcurrentPage=facesContext.getViewRoot().getViewId();System.out.println("PAGINA DE DESTINO after: "+currentPage);booleanisLoginPage=(currentPage.lastIndexOf("login.jsp")<-1);HttpSessionsession=(HttpSession)facesContext.getExternalContext().getSession(true);System.out.println("=======validado a página=======");UsuariocurrentUser=(Usuario)session.getAttribute("currentUser");if(!isLoginPage&¤tUser==null){NavigationHandlernh=facesContext.getApplication().getNavigationHandler();System.out.println("<-------condicao lançada-------->");nh.handleNavigation(facesContext,null,"loginPage");System.out.println("<-------usuario nao logado-------->");}else{FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("currentUser",currentUser);System.out.println("========leu o else=========");}}publicvoidbeforePhase(PhaseEventevent){System.out.println("PRINT DE IDENTIFICAÇÃO DO EVENTO before: "+event.getPhaseId());}publicPhaseIdgetPhaseId(){returnPhaseId.RESTORE_VIEW;}}
Já li um pouco sobre ele, mas eu não queria fazer essa mudança drástica na minha aplicação já iniciada. E além disso, todos os tutoriais que eu vi sobre o JAAS não se usa o postgres.
Eu tenho encontrado muita dificuldade na resolução de problemas aqui no fórum. As pessoas visitam as páginas, mas não postam nada. Ou por falta de tempo, ou por falta de interesse em ajudar. Por isso, quero te agradecer por ter respondido.
Mas se você quer alterar a estrutura da arvore através do getViewId() para dar os rendered(false) nos componentes que não deve aparecer, você não vai conseguir, porque antes da fase RENDER_RESPONSE vc ainda não tem a estrutura da pagina que será exibida, e depois da fase RENDER_RESPONSE todas as alterações que você fizer não vão para a tela.
rsakurai, estou com esse mesmo problema. Quero fazer um controle de acesso a nível de componentes através do phase listener. Você conseguiu alguma coisa?
J
jomello_br
Minha solução para o problema:
Crie u Listner:
/*
To change this template, choose Tools | Templates
and open the template in the editor.
*/
package br.cep.filter;
@author joao
*/
public class AuthorizationListener implements PhaseListener {
// REPRESENTA A LISTA DE PÁGINA QUE O USUÁRIO PODE ACESSAR
private String[] paginasAutorizadas = new String[]{"/jsp/login.xhtml", “/jsp/dashBoard.xhtml”, “/jsp/consultarCliente.xhtml”};
//RESPONSÁVEL POR VERIFICAR SE O USUÁRIO ESTA AUTORIZADOpublicbooleanverificarAutorizacao(StringpaginaRequisitada){/*for(Stringpagina:paginasAutorizadas){if(paginaRequisitada.equals(pagina)){returntrue;}}returnfalse;**/returntrue;}
/**
Método chamado sempre apósa execução de uma determinada PHASE
//CONFORME DITO ANTERIORMENTE MESMO SEM O USO DE NA FASE// APPLY_REQUEST_VALUES O NOME DA PÁGINA ESTARA ATUALIZADO, PORTANTO E//NESSA FASE QUE PODEMOS VERIFICAR SE O USUÁRIO ESTA AUTORIZADO A ACESSAR//A PÁGINA REQUISITADA// if (event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)) {ctx=event.getFacesContext();//CAPTURA O USUÁRIO LOGADO POIS SE ESTA FASE FOR EXECUTADA SIGNIFICA QUE EXISTE USUÁRIO AUTENTICADOHttpSessionsession=(HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(true);ObjectusuarioLogado=session.getAttribute("currentUser");if(usuarioLogado!=null){Logado=true;}StringurlDestino=ctx.getViewRoot().getViewId();booleanisLoginPage=(urlDestino.lastIndexOf("login.jsp")>-1);//VALIDA A AUTORIZAÇÃO PARA ACESSAR A PÁGINAif(!Logado&&!isLoginPage){NavigationHandlernh=ctx.getApplication().getNavigationHandler();nh.handleNavigation(ctx,null,"loginPage");}
}
}
/**
** Método chamado sempre antes de se executar uma determinada PHASE
if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW)) {
//AQUI DEVE FICAR A LÓGICA PARA VERIFICAR SE EXISTE UM USUÁRIO
//AUTENTICADO NA APLICAÇÃO
ctx = event.getFacesContext();
//verifica se existe um usuário autenticado
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
if (session.getAttribute(“usuarioLogado”) == null) {
try {
//se não existir direciona para a página de LOGIN
ctx.getExternalContext().redirect("/pages/login/login.jsp");
} catch (IOException ex) {
Logger.getLogger(AuthorizationListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
*
*/
}
/**
Retorna o PhaseId da fase do ciclo de vida JSF que
esta sendo interceptado e gerênciado pelo Controle de acesso.