Pessoal , bom dia , eu estou criando uma aplicação e eu quero criar um filtro de segurança para isso eu criei uma classe que implementa PhaseListener e eu declarei ela no faces-config.xml .
Porém eu estou com um problema , quando eu executo uma action no managed bean ele passa pelo phase listener , só que quando eu digito a url no browser da página ele não passa pelo filtro , alguém teria uma dica para criação deste filtro?
Obrigado.
Se você declarou corretamente esse listener ele é executado na fase do ciclo de vida que você definiu indiferente se a página foi chamada por uma ação ou diretamente pelo browser.
O que pode estar acontecendo é que você não está fazendo o tratamento necessário.
Não sei exatamente qual tratamento você quer fazer mas por exemplo caso o usuário não esteja logado você pode redirecionar para uma página de login:
NavigationHandler nh = facesContext.getApplication().getNavigationHandler();
nh.handleNavigation(facesContext, null, "notAuthorized");
e no faces config definir uma navigation-rule como:
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>notAuthorized</from-outcome>
<to-view-id>/error.jsp</to-view-id>
</navigation-case>
</navigation-rule>
O meu listener eu fiz da seguinte forma.
public void afterPhase(PhaseEvent phaseEvent) {
FacesContext context = phaseEvent.getFacesContext();
NavigationHandler nh = context.getApplication().getNavigationHandler();
String viewID = context.getViewRoot().getViewId().replaceAll("/","");
if(!"login".equals(viewID)){
List<String> userRoles = JSFManagedBeanUtility.getUserRoles(context);
boolean authorized = userRoles.contains(viewID);
boolean isLoggedOn = JSFManagedBeanUtility.isUserLoggedOn(context);
if(!authorized && isLoggedOn){
ResourceBundle bundle = ResourceBundle.getBundle(context.getApplication().getMessageBundle());
FacesMessage message =
new FacesMessage(bundle.getString("authorizationException.message"));
message.setSeverity(FacesMessage.SEVERITY_ERROR);
Iterator facesMessagesIt = FacesContext.getCurrentInstance().getMessages();
if(!facesMessagesIt.hasNext()){
FacesContext.getCurrentInstance().addMessage(null, message);
}
nh.handleNavigation(context,null,"notAuthorizedPage");
}
else if(!isLoggedOn){
nh.handleNavigation(context,null,"login");
}
}
}
/**
* Do nothing
* @param phaseEvent the phaseEvent
* */
public void beforePhase(PhaseEvent phaseEvent) {
}
/**
* Return the phase id for this filter
* */
public PhaseId getPhaseId() {
return PhaseId.INVOKE_APPLICATION;
}
}
Estou com dúvida no retorno deste phaseId , será que o valor está correto ? Ou eu preciso mudar alguma coisa ?
Obrigado.
Não está correto, procure artigos/tutoriais sobre o ciclo de vida do JSF para endender melhor as fases.
Só uma rápida solução troque o retorno do método getPhaseId para PhaseId.RESTORE_VIEW.
Você tem alguma sugestão ou referência , meu problema é que quando ele cai na página da home utilizando a fase Restore_VIEW ele não consegue entrar nas anteriores, eu preciso de uma segurança baseada em role , você tem alguma idéia ?
Obrigado.
Luiszerba
Nesse link tem uma classe, esta todos os processos e fases das requisições.
Estou certo que vai esclarecer tudo. E implementar o que deseja.
Sds