Olá amigos, boa noite.
Estarei explicando agora como realizar a autenticação dos usuários para acesso a determinadas páginas do sistema. Caso a página não seja permitida ao seu perfil, e o mesmo informá-la manualmente na URL, o mesmo será redirecionado para a página principal. Segue o código abaixo.
Trecho do ManagedBean AutenticacaoController.java
/**
*
* @author Lessandro
*/
@ManagedBean(name = "autenticacaoController")
@ViewScoped
public class AutenticacaoController {
private Usuario usuario, usuarioAutenticado;
private UsuarioDAO usuarioDAO;
private HttpSession session;
@PostConstruct
public void init() {
//Chamado só quando o managed bean é colocado no escopo view,
//e não a cada requisição como acontecia com o escopo request
usuario = new Usuario();
}
@PreDestroy
public void destroy() {
/* chamado quando outra view for chamada através do UIViewRoot.setViewId(String viewId) */
}
// Método responsável por realizar a autenticação do usuário, e setar para a variável de sessão usuarioAutenticado o usuário recuperado do BD, para este ser recuperado posteriormente no PhaseListener, e lá verificamos na fase de visão se este pode realizar tal acesso. O botão Login na página JSF chama esse método
public void autenticaUsuario() {
try {
usuarioDAO = new UsuarioDAO();
usuarioAutenticado = usuarioDAO.buscaLoginSenha(usuario.getDsLogin(), usuario.getDsSenha());
if (usuarioAutenticado == null) {
JsfUtil.addErrorMessage("iphMensagem", ResourceBundle.getBundle("/message").getString("usuario.naoEncontrado"));
} else {
FacesContext ctx = FacesContext.getCurrentInstance();
session = (HttpSession) ctx.getExternalContext().getSession(false);
session.setAttribute("usuarioAutenticado", usuarioAutenticado);
System.out.println(session.getId());
}
} catch (Exception e) {
JsfUtil.addErrorMessage("iphMensagem", ResourceBundle.getBundle("/message").getString("mensagem.conexao.erro"));
}
}
// Método responsável por remover o usuário da sessão quando o mesmo realiza logout. O botão sair chama este método.
public void encerraSessao() {
try {
FacesContext ctx = FacesContext.getCurrentInstance();
session = (HttpSession) ctx.getExternalContext().getSession(false);
session.setAttribute("usuarioAutenticado", null);
ctx.getExternalContext().redirect(ctx.getExternalContext().getRequestContextPath() + "/app" + Constantes.PAGINA_INDEX);
session.invalidate();
} catch (Exception e) {
}
}
Agora implementamos a classe FaseListener que implementa a classe PhaseListener.
FaseListener.java
/**
*
* @author Lessandro
*/
public class FaseListener implements PhaseListener {
private static final long serialVersionUID = 1L;
public FaseListener() {
}
@Override
public void afterPhase(PhaseEvent event) {
FacesContext fc = event.getFacesContext();
ExternalContext ec = fc.getExternalContext();
if (StringUtils.isNotBlank(Constantes.PAGINA_INDEX)) {
try {
// workaround for PrimeFaces
new RequestContextImpl(ec);
if (ec.getRequestParameterMap().containsKey(Constants.PARTIAL_PROCESS_PARAM) && !ec.getRequestParameterMap().get(Constants.PARTIAL_PROCESS_PARAM).equals("@all")) {
fc.setViewRoot(new PartialViewRoot(new UIViewRoot()));
}
// fix for renderer kit (Mojarra's and PrimeFaces's ajax redirect)
if ((RequestContext.getCurrentInstance().isAjaxRequest() || fc.getPartialViewContext().isPartialRequest()) && fc.getResponseWriter() == null && fc.getRenderKit() == null) {
ServletResponse response = (ServletResponse) ec.getResponse();
ServletRequest request = (ServletRequest) ec.getRequest();
response.setCharacterEncoding(request.getCharacterEncoding());
RenderKitFactory factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
RenderKit renderKit = factory.getRenderKit(fc, fc.getApplication().getViewHandler().calculateRenderKitId(fc));
ResponseWriter responseWriter = renderKit.createResponseWriter(response.getWriter(), null, request.getCharacterEncoding());
fc.setResponseWriter(responseWriter);
}
HttpSession session = (HttpSession) ec.getSession(true);
/* Aqui recuperamos o usuário autenticado setado no MB autenticacaoController */
Usuario usuario = (Usuario) session.getAttribute("usuarioAutenticado");
// Quando o usuário informar na URL manualmente a página de exibição de perfis ou usuários, o qual permite remover um usuário ou perfil existente no sistema, verificamos se o ID do perfil deste usuário autenticado é Administrador, caso não seja, redirecionamos o mesmo para a página principal, não permitindo acesso à tal página. Este modelo pode ser implementado para qualquer outra página a qual não deseje que o usuário tenha acesso.
if ((usuario != null && !usuario.getPerfil().getIdPerfil().equals(Constantes.ID_PERFIL_ADMINISTRADOR)) && (fc.getViewRoot().getViewId().contains(Constantes.PAGINA_EXIBIR_PERFIL) || fc.getViewRoot().getViewId().contains(Constantes.PAGINA_EXIBIR_USUARIO))) {
ec.redirect(ec.getRequestContextPath() + "/app" + Constantes.PAGINA_INDEX);
}
} catch (IOException e) {
System.out.println("Redirect to the specified login page " + Constantes.PAGINA_INDEX + " failed");
throw new FacesException(e);
}
}
}
@Override
public void beforePhase(PhaseEvent event) {
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
JSFUtil.java
package br.com.notaroberto.util;
//~--- JDK imports ------------------------------------------------------------
import java.lang.reflect.Method;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
public class JsfUtil {
public static void addErrorMessageExcecao(Exception ex, String defaultMsg) {
String msg = ex.getLocalizedMessage();
if ((msg != null) && (msg.length() > 0)) {
addErrorMessage(null, msg);
} else {
addErrorMessage(null, defaultMsg);
}
}
public static void addErrorMessages(List<String> messages) {
for (String message : messages) {
addErrorMessage(null, message);
}
}
public static void addErrorMessage(String idComponente, String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(idComponente, facesMsg);
}
public static void addSuccessMessage(String idComponente, String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
FacesContext.getCurrentInstance().addMessage("idComponente", facesMsg);
}
public static String getRequestParameter(String key) {
return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);
}
public static Object getObjectFromRequestParameter(String requestParameterName, Converter converter,
UIComponent component) {
String theId = JsfUtil.getRequestParameter(requestParameterName);
return converter.getAsObject(FacesContext.getCurrentInstance(), component, theId);
}
public static Object getMethod(Object obj, String name) throws Exception {
Method createMethod = obj.getClass().getMethod(name, new Class[0]);
return createMethod.invoke(obj, new Object[0]);
}
public static void setAttribute(String valorObjeto, Object tipoObjeto) {
FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(valorObjeto, tipoObjeto);
}
public static Object getAttribute(String valorObjeto) {
return FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(valorObjeto);
}
}
Finalizando, precisamos informá-lo no faces-config.xml. O caminho do meu FaseListener está em: br.com.notaroberto.control, no caso de vocês basta alterá-lo:
<lifecycle>
<phase-listener>br.com.notaroberto.control.FaseListener</phase-listener>
</lifecycle>
É isso aí amigos. Espero que possa ajudá-los. Essa classe foi feita exclusivamente para quem está utilizando o primefaces, pois o redirecionamento “padrão” de página encontrado aí pela net não funciona com este framework, sendo exibida a mensagem: “java.lang.IllegalStateException”.
Abs,
Lessandro