Libro JEE7 05. Login y Seguridad
- ROLES
- CREAR CDI BEANS para administrar los roles
- CREAR CDI RolAdministrador
- CREAR CDI ValidadorRoles
- CREAR CDI LoginBean
- Codigo completo de LoginBean.java
- EDITAR LA PAGINA index.xhtml
- EDITAR LA PAGINA menu.xhtml
- CREAR LA PĆGINA accesodenegado.xhtml
- EDITAR LA PĆGINA estatusinsert.xhtml
https://www.dropbox.com/sh/yzivtufjce1h57g/AAAJzegPVBxFtiqzEOlIAdsoa?dl=0
En este capĆtulo mostraremos cĆ³mo crear el formulario de login y realizar las validaciones necesarias de los privilegios.
TambiƩn colocaremos los formularios en un diƔlogo visible.
ROLES
Para validar los roles de usuarios tenemos varias alternativas, en esta ocasiĆ³n lo controlaremos desde CDI Beans.
Crearemos un CDI Beans llamado MenuBeans que contendrĆ” las opciones del menĆŗ y los privilegios que tiene el usuario en cada opciĆ³n.
- Desde menĆŗ File, seleccione New
- en Categories, seleccione Java Server Faces
- en File Types, seleccione JSF ManagedBeans
- Class Name: MenuBeans
- Package com.avbravo.scrumweb.generales
- Scope: Session
Recordar cambiar las anotaciones y los imports.
Si observamos el menĆŗ, contamos con la opciĆ³n Registros y dentro de ella Estatus con dos menuitems, Insertar, Listar.
Definiremos atributos booleanos para los diversos componentes.
Definiremos:
- Los elementos de la barra con el formato: barraNombre
- private Boolean barraRegistros = false;
- Los menĆŗ con el formato: nombreMenu
- private Boolean estatusMenu = false;
- Los submenu con el formato: nombreOperacion
- private Boolean estatusCrear = false;
Generamos los get/set mendiante , clic derecho en el cĆ³digo y seleccionar Insert Code→Getters and Setterts
Nota:
El cĆ³digo generado como son atributos booleanos se generan los mĆ©todos is, en nuestro CDI Beans debemos cambiarlo a get para utilizarlo dentro de nuestras pĆ”ginas java server faces.
public Boolean isBarraRegistros() {
return barraRegistros;
}
public void setBarraRegistros(Boolean barraRegistros) {
this.barraRegistros = barraRegistros;
}
Cambiamos is por get, los mƩtodos set quedan iguales no se modifican.
public Boolean getBarraRegistros() {
return barraRegistros;
}
public void setBarraRegistros(Boolean barraRegistros) {
this.barraRegistros = barraRegistros;
}
Codigo completo de MenuBeans.java
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
/**
*
* @author avbravo
*/
@Named
@SessionScoped
public class MenuBeans implements Serializable {
private static final long serialVersionUID = 1L;
/*
* barra de menu
*/
private Boolean barraRegistros = false;
/*
*/
private Boolean estatusMenu = false;
private Boolean estatusCrear = false;
private Boolean estatusConsultar = false;
private Boolean estatusEditar = false;
private Boolean estatusListar = false;
private Boolean estatusEliminar = false;
//Crear el mƩtodo habilitarTodo(Boolean activo), que recibi un parƔmetro de tipo //booleano y que serƔ asignado a los todos los atributos del CDI Beans.
public void habilitarTodo(Boolean activo) {
/*
barra
*/
barraRegistros = activo;
estatusMenu = activo;
estatusCrear = activo;
estatusConsultar = activo;
estatusEditar = activo;
estatusListar = activo;
estatusEliminar = activo;
}
public Boolean getBarraRegistros() {
return barraRegistros;
}
public void setBarraRegistros(Boolean barraRegistros) {
this.barraRegistros = barraRegistros;
}
public Boolean getEstatusMenu() {
return estatusMenu;
}
public void setEstatusMenu(Boolean estatusMenu) {
this.estatusMenu = estatusMenu;
}
public Boolean getEstatusCrear() {
return estatusCrear;
}
public void setEstatusCrear(Boolean estatusCrear) {
this.estatusCrear = estatusCrear;
}
public Boolean getEstatusConsultar() {
return estatusConsultar;
}
public void setEstatusConsultar(Boolean estatusConsultar) {
this.estatusConsultar = estatusConsultar;
}
public Boolean getEstatusEditar() {
return estatusEditar;
}
public void setEstatusEditar(Boolean estatusEditar) {
this.estatusEditar = estatusEditar;
}
public Boolean getEstatusListar() {
return estatusListar;
}
public void setEstatusListar(Boolean estatusListar) {
this.estatusListar = estatusListar;
}
public Boolean getEstatusEliminar() {
return estatusEliminar;
}
public void setEstatusEliminar(Boolean estatusEliminar) {
this.estatusEliminar = estatusEliminar;
}
}
CREAR CDI BEANS para administrar los roles
Pasos:
Crearemos un CDI Beans para cada rol, donde indicaremos los privilegios que tiene en base a su rol, y el CDI Beans ValidadorRoles, a continuaciĆ³n mostraremos la imagen de como seria nuestro paquete con los CDI Beans, si observamos existe un CDI para cada rol.
CREAR CDI RolAdministrador
- Desde menĆŗ File, seleccione New
- en Categories, seleccione Java Server Faces
- en File Types, seleccione JSF ManagedBeans
- Class Name: RolAdministrador
- Package com.avbravo.scrumweb.roles
- Scope: request
Inyectamos MenuBeans
@Inject
MenuBeans menuBeans;
y creamos el mĆ©todo activar(), donde asignamos valores de true a los atributos correspondientes a los roles, si deseamos que el usuario no tenga acceso a una opciĆ³n simplemente asignamos un valor de false.
public void activar() {
menuBeans.setBarraRegistros(true);
menuBeans.setEstatusMenu(true);
menuBeans.setEstatusCrear(true);
menuBeans.setEstatusConsultar(true);
menuBeans.setEstatusEditar(true);
menuBeans.setEstatusListar(true);
menuBeans.setEstatusEliminar(true);
}
CĆ³digo completo de RolAdministrador.java
import com.avbravo.scrumweb.generales.MenuBeans;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author avbravo
*/
@Named
@RequestScoped
public class RolAdministrador {
@Inject
MenuBeans menuBeans;
/**
* Creates a new instance of RolAdministrador
*/
public RolAdministrador() {
}
public void activar() {
menuBeans.setBarraRegistros(true);
menuBeans.setEstatusMenu(true);
menuBeans.setEstatusCrear(true);
menuBeans.setEstatusConsultar(true);
menuBeans.setEstatusEditar(true);
menuBeans.setEstatusListar(true);
menuBeans.setEstatusEliminar(true);
}
}
De la misma forma creamos los CDI Beans RolDuenoProducto y en el mĆ©todo activar de cada uno de ellos establecemos los privilegios para acceder o no cada opciĆ³n.
CREAR CDI ValidadorRoles
- Desde menĆŗ File, seleccione New
- en Categories, seleccione Java Server Faces
- en File Types, seleccione JSF ManagedBeans
- Class Name: ValidadorRoles
- Package com.avbravo.scrumweb.roles
- Scope: request
Pasos:
- Inyectamos los CDI Beans de roles
- Inyectamos MenuBeans
- Crear un mƩtodo validarRoles(String rolvalidacion), que recivira un parƔmetro que indica el rol y este serƔ validado llamando al mƩtodo activar(), del CDI Beans correspondiente.
- Si no existe un rol especifico se desactivara todos las opciones de los menu, invocando a menuBeans.habilitarTodo(false);
CĆ³digo completo de ValidadorRoles.java
import com.avbravo.scrumweb.generales.JSFUtil;
import com.avbravo.scrumweb.generales.MenuBeans;
import com.avbravo.scrumweb.generales.ResourcesFiles;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author avbravo
*/
@Named
@RequestScoped
public class ValidadorRoles {
@Inject
RolAdministrador rolAdministrador;
@Inject
RolDuenoProducto rolDuenoProducto;
@Inject
MenuBeans menuBeans;
@Inject
ResourcesFiles rf;
/**
* Creates a new instance of ValidadorRoles
*/
public ValidadorRoles() {
}
public Boolean validarRoles(String rolvalidacion) {
Boolean ok = Boolean.TRUE;
try {
switch (rolvalidacion) {
case "administrador":
rolAdministrador.activar();
break;
case "product owner":
rolDuenoProducto.activar();
break;
default:
menuBeans.habilitarTodo(false);
ok = Boolean.FALSE;
JSFUtil.warningDialog(rf.getMensajeArb("warning.title"), rf.getMensajeArb("info.sinrolasignado"));
}
} catch (Exception e) {
JSFUtil.addErrorMessage("validarRoles() " + e.getLocalizedMessage());
}
return ok;
}
}
CREAR CDI LoginBean
- Desde menĆŗ File, seleccione New
- en Categories, seleccione Java Server Faces
- en File Types, seleccione JSF ManagedBeans
- Class Name: LoginBean
- Package com.avbravo.scrumweb.generales
- Scope: Session
Pasos:
- Inyectamos Usuarios, UsuariosFacade,ResourcesFiles, MenuBeans,ValidadorRoles
- Crear metodos get/set para el Entity Usuarios.
- Crear atributo Boolean logeado y los @Inject
- RolAdministrador rolAdministrador;
- @Inject
- RolDuenoProducto rolDuenoProducto;
- mƩtodos set/get. Recordar cambiar el mƩtodo is por get.
- Crear el mĆ©todo verificarLogin(), en este mĆ©todo se validarĆ” el username y password del usuario y el rol que tiene el mismo dentro de la aplicaciĆ³n.
- Crear metodo logout()
- Crear mƩtodo init()
Codigo completo de LoginBean.java
import com.avbravo.scrumweb.Usuarios;
import com.avbravo.scrumweb.ejb.UsuariosFacade;
import com.avbravo.scrumweb.roles.ValidadorRoles;
import java.io.IOException;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
@Named
@SessionScoped
public class LoginBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
UsuariosFacade usuariosFacade;
Usuarios usuarios = new Usuarios();
@Inject
ResourcesFiles rf;
@Inject
MenuBeans menuBeans;
@Inject
ValidadorRoles validadorRoles;
Boolean logeado = false;
/**
* Creates a new instance of LoginBean
*/
public Usuarios getUsuarios() {
return usuarios;
}
public void setUsuarios(Usuarios usuarios) {
this.usuarios = usuarios;
}
public Boolean getLogeado() {
return logeado;
}
public void setLogeado(Boolean logeado) {
this.logeado = logeado;
}
@PostConstruct
public void init() {
}
public LoginBean() {
}
public String verificarLogin() {
try {
menuBeans.habilitarTodo(false);
setLogeado(Boolean.FALSE);
Usuarios u = usuariosFacade.find(usuarios.getUsername());
if (u == null) {
JSFUtil.addWarningMessage(rf.getMensajeArb("login.usernamenotvalid"));
return null;
}
if (!u.getActivo().equals("si")) {
JSFUtil.addSuccessMessage(rf.getMensajeArb("login.inactive"));
return "";
}
if (!u.getPassword().equals(usuarios.getPassword())) {
JSFUtil.addSuccessMessage(rf.getMensajeArb("login.passwordnotvalid"));
return "";
}
usuarios = u;
setLogeado(Boolean.TRUE);
if (validadorRoles.validarRoles(usuarios.getIdgruposusuario().getIdgruposusuario())) {
return "";
}
} catch (Exception e) {
JSFUtil.addErrorMessage(e, "verificarLogin()");
}
return null;
}
public String logout() {
try {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
if (session != null) {
session.invalidate();
}
String url = "/scrumweb/faces/index.xhtml?faces-redirect=true";
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
try {
ec.redirect(url);
} catch (IOException ex) {
JSFUtil.addErrorMessage(ex.getLocalizedMessage());
}
return "/scrumweb/faces/index.xhtml?faces-redirect=true";
} catch (Exception e) {
JSFUtil.addErrorMessage(e, "logout()");
}
return null;
}
public String irLogin() {
return "/index";
}
public void irInicio() {
FacesContext ctx = FacesContext.getCurrentInstance();
ExternalContext extContext = ctx.getExternalContext();
String url = extContext.encodeActionURL(ctx.getApplication().getViewHandler().getActionURL(ctx, "/index.xhtml"));
try {
extContext.redirect(url);
} catch (IOException ioe) {
JSFUtil.addErrorMessage(ioe.getLocalizedMessage().toString());
}
}
}
EDITAR LA PAGINA index.xhtml
Colocar las etiquetas para validar el login de usuario.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<body>
<ui:composition template="./template.xhtml">
<!--
<ui:define name="top">
top
</ui:define>
<ui:define name="bottom">
bottom
</ui:define>
<ui:define name="left">
left
</ui:define>
-->
<ui:define name="center">
<h:form id="formtopnologeado" rendered="#{!loginBean.logeado}" >
<p:growl id="growl" life="1500" />
<p:dialog visible="true" header="#{app['application.title']}" closable="false" showEffect="clip" hideEffect="fade" widgetVar="loginDialog">
<h:panelGrid columns="2" >
<f:facet name="header">
<h:outputLabel value="#{mensajes['boton.login']}"/>
</f:facet>
<h:outputText value="#{app['login.username']}"></h:outputText>
<h:inputText value="#{loginBean.usuarios.username}" required="true" />
<h:outputText value="#{app['login.password']}" ></h:outputText>
<h:inputSecret value="#{loginBean.usuarios.password}" required="true" />
<f:facet name="footer">
<p:commandButton action="#{loginBean.verificarLogin}" value="#{app['boton.login']}" ajax = "false" />
</f:facet>
</h:panelGrid>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
EDITAR LA PAGINA menu.xhtml
Editar las opciones y colocar la validaciĆ³n para activar las opciones en base al valor de los atributos de menuBeans.
Paso:
- Colocar la propiedad rendered en el <p:megaMenu> utilizando el atributo logeado de loginBean.
- Utilizar rendered en el submenĆŗ utilizando barraRegistros
- Utilizar el atributo rendered de los <menuitem> utilizando estatusCrear y estatusListar.
el rendered y el atributo de menuBeans correspondientes, para establecer la validaciĆ³n.
- Colocar en el menuitem logout actionListener="#{loginBean.logout}" ajax = "false" rendered="#{loginBean.logeado}"
<h:body>
<ui:composition>
<h:form id="menuForm" >
<p:megaMenu rendered="#{loginBean.logeado}">
<p:submenu label="#{app['menu.records']}" rendered="#{menuBeans.barraRegistros}" icon="ui-icon-check">
<p:column>
<p:submenu label="#{app['menu.estatus']}" rendered="#{menuBeans.estatusMenu}">
<p:menuitem value="#{app['menu.insert']}" rendered="#{menuBeans.estatusCrear}" url="/faces/page/estatus/estatusinsert.xhtml" />
<p:menuitem value="#{app['menu.list']}" rendered="#{menuBeans.estatusListar}" url="/faces/page/estatus/estatuslist.xhtml"/>
</p:submenu>
</p:column>
</p:submenu>
<p:menuitem value="#{app['login.logout']}" actionListener="#{loginBean.logout}" title="#{app['login.logout']}" ajax = "false" rendered="#{loginBean.logeado}" icon="ui-icon-power"/>
CREAR LA PĆGINA accesodenegado.xhtml
Esta pƔgina la usaremos para desplegar un mensaje indicando que el usuario no tiene privilegios para visualizar la pƔgina, generalmente ocurre cuando el usuario trata de ingresar el url en el navegador para ingresar a paginas no autorizadas.
Pasos:
- Crear el Facelets Template Client
- Agregar un dialogo visible
- Mostrar un texto
- Utilizar un boton para enviarlo a la pagina para logearse.
Ahora creamos un Facelets Template Client
- Desde menĆŗ File, seleccione New
- en Categories, seleccione Java Server Faces
- en File Types, JSF Page
- En File Name: accesodenegado
Colocamos un diĆ”logo, con un panelGrid donde colocamos una etiqueta y un botĆ³n para regresar al index.xhtml.
CĆ³digo completo de accesodenegado.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:body>
<ui:composition>
<p:dialog visible="true" header="#{app['login.accesodenegado']}" closable="false" showEffect="fade" hideEffect="fade" widgetVar="loginDialog">
<p:panelGrid columns="1" >
<h:outputText value="#{app['login.accesodenegadoDetalle']}"/>
<p:commandButton action="#{loginBean.irLogin}" value="#{app['boton.return']}" ajax="false"/>
</p:panelGrid>
</p:dialog>
</ui:composition>
</h:body>
</html>
EDITAR LA PĆGINA estatusinsert.xhtml
Estableceremos validaciĆ³n de acceso a nivel de cada pĆ”gina para solo permitir el ingreso al usuario con los privilegios.
Pasos:
- Establecer el rendered con la opciĆ³n de menuBeans en el form principal
<ui:define name="center">
<f:view>
<h:form rendered="#{menuBeans.estatusCrear}">
colocar en comentarios
<!-- <h1><h:outputText value="#{app['form.estatusnew']}"/></h1>-->
- Colocar un dialogo
<p:dialog visible="true" header="#{app['form.estatusnew']}" closable="true" showEffect="clip" hideEffect="fade" widgetVar="estatusinsertDialog">
cerramos el diƔlogo despuƩs </h:panelGrid>
</p:dialog>
- Agregar el include accesodenegado si no se tiene permisos para ingresar al formulario.
antes del </f:view> fuera del form principal.
<h:form rendered="#{!menuBeans.estatusCrear}">
<ui:include src="/accesodenegado.xhtml" />
</h:form>
</f:view>
se mostrarƔ en un diƔlogo el formulario
Repetimos el proceso para la pƔgina estatuslist.xhtml usando el rendered
<h:form id="form" rendered="#{menuBeans.estatusListar}">
Colocamos el datatable en un dialogo.
<p:dialog visible="true" header="#{app['form.estatuslist']}" closable="false" showEffect="clip" hideEffect="fade" widgetVar="estatuslistDialog">
<p:dataTable id="datatable" paginator="true"
rows="7" value="#{estatusDataController.estatusList}" var="item"
rowKey="#{item.idestatus}"
selectionMode="single"
selection="#{estatusDataController.selected}"
filteredValue="#{estatusDataController.filtered}"
>
</p:dataTable>
</p:dialog>
Agregamos el include con el rendered.
<h:form rendered="#{!menuBeans.estatusListar}">
<ui:include src="/accesodenegado.xhtml" />
</h:form>
Para probarlo podemos pegar en el browser el url
Sin haberse logueado y mostrarƔ el diƔlogo de acceso denegado, y al presionar el boton Regresar nos lleva a la pƔgina index.html donde nos debemos loguear.
De esta manera restringimos el acceso por privilegios a cada pƔgina
Comments
Your site provided us with helpful info to work on. You've done a formidable process and our whole neighborhood might be grateful
to you.
getting that type of info written in such an ideal approach?
I have a venture that I'm just now running on, and I have been at the look
out for such info.
for the reason that here every material is quality based stuff.
me. And i'm glad reading your article. But wanna remark on few general things, The website
style is wonderful, the articles is really excellent
: D. Good job, cheers