Archive
La Seguridad Perfecta con Spring y el dropDownMenu de RichFaces
Bueno, sigo con la seguridad de Spring 2.0 o el conocido como el antiguo Acegi Security, ahora voy a proponer una alternativa para generar una seguridad con un componente de RichFaces, el dropDownMenu. ToolBar y menuItem.
Primero te recomiendo sigas la configuración de Spring con JDBC, o con LDAP, como tu lo desees, porque de todas formas todos los Roles ( o Permisos) quedan almacenados en la misma variable de Spring. También si deseas integrarlo con Facelest, aqui tenes los pasos a seguir.
Lo primero que hay que hacer, es construir el menú, para eso usamos un Tool Bar:
<rich:toolBar> <rich:dropDownMenu > <f:facet name="label"> <h:panelGroup> <h:graphicImage value="#{initParam['rootimages']}/images/icons/contexthelp.png" /> <h:outputText value="JotaDeveloper" /> </h:panelGroup> </f:facet> <rich:menuItem submitMode="ajax" value="Articulos"></rich:menuItem> <rich:menuItem submitMode="ajax" value="Tutoriales"></rich:menuItem> <rich:menuItem submitMode="ajax" value="Ayuda"></rich:menuItem> </rich:dropDownMenu> </rich:toolBar>
El código es bien sencillo, no hace falta explicar mucho, solo que para poder colocar un dropDownMenu , es necesario el toolBar, y para el menuItem , debe estar dentro de un dropDownMenu.
Depues de esto, y espero que hayas leido los 3 articulos que sugerí anteriormente, vamos a crear un Bean, donde tendremos la logica de nuestra seguridad con el dropDownMenu.
import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.Authentication; import org.springframework.security.GrantedAuthority; import org.springframework.security.context.SecurityContext; import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.ui.WebAuthenticationDetails; public class JotaDeveloperMenuBean { // Un objeto Booleano por cada elemento del Menu private Boolean rootJotaDeveloper; private Boolean rootTutoriales; private Boolean rootArticulos; private Boolean rootAyuda; // Objetos Spring Security private Object seguridadAcegi; // El GrantedAuthority es un Array con todos los Roles que recupera de la BD private GrantedAuthority[] listaAutoridades; private SecurityContext contexto; private Authentication autenticacion; private List<String> ListAutoridades = new ArrayList<String>(); private String nombreUsuario; private Boolean estaAutenticado; private WebAuthenticationDetails webAu; /** * Constructor que accede a toda la información de Spring Security */ public JotaDeveloperMenuBean() { this.seguridadAcegi = SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); this.contexto = SecurityContextHolder.getContext(); this.autenticacion = SecurityContextHolder.getContext() .getAuthentication(); this.listaAutoridades = SecurityContextHolder.getContext() .getAuthentication().getAuthorities(); convertirArrayAuthoritiesToListAuthorities(); this.nombreUsuario = this.autenticacion.getName(); this.estaAutenticado = this.autenticacion.isAuthenticated(); } /** * Este metodo convierte el Array de Roles poco manejable en un List */ private void convertirArrayAuthoritiesToListAuthorities() { int it_cont; for (it_cont = 0; it_cont < listaAutoridades.length; it_cont++) { String ROL = listaAutoridades[it_cont].toString(); ListAutoridades.add(ROL); } } /** * Comprueba si existe determinado Rol en la Lista de Autoridades del * Usuario Logeado * * @param cadena * ROL * @return El resultado de la Busqueda */ private Boolean comprobarRol(String cadena) { Integer id = ListAutoridades.indexOf(cadena); // Si el Id es -1, el valor no fue encontrado. if (id != -1) { return false; } else { return true; } } /** * Los Getters que va leer cada elemento del Menu */ public Boolean getRootJotaDeveloper() { return rootJotaDeveloper = comprobarRol("ROLE_ROOT_JOTADEVELOPER"); } public Boolean getRootTutoriales() { return rootTutoriales = comprobarRol("ROLE_ROOT_TUTORIALES"); } public Boolean getRootAyuda() { return rootArticulos = comprobarRol("ROLE_ROOT_AYUDA"); } public Boolean getRootArticulos() { return rootAyuda = comprobarRol("ROLE_ROOT_ARTICULOS"); } }
Despues de esto y incluir el Bean el el ManageBean de faces-config.xml, solo agregamos a la propiedad disabled del MenuItem el get del Bean.
<rich:toolBar> <acegijsf:authorize ifAllGranted="ROLE_ROOT_JOTADEVELOPER"> <rich:dropDownMenu > <f:facet name="label"> <h:panelGroup> <h:graphicImage value="#{initParam['rootimages']}/images/icons/contexthelp.png" /> <h:outputText value="JotaDeveloper" /> </h:panelGroup> </f:facet> <rich:menuItem submitMode="ajax" value="Articulos" disabled="#{jotaDeveloperMenuBean.rootArticulos}"></rich:menuItem> <rich:menuItem submitMode="ajax" value="Tutoriales" disabled="#{jotaDeveloperMenuBean.rootTutoriales}"></rich:menuItem> <rich:menuItem submitMode="ajax" value="Ayuda" disabled="#{jotaDeveloperMenuBean.rootAyuda}"></rich:menuItem> </rich:dropDownMenu> </acegijsf:authorize> </rich:toolBar>
El resultado de todo esto, es que cuando inices sesión, el GrantedAuthority que genera en la sesión del usuario Spring Security, lo convertimos en un List, luego cada elemente del menu que tu crees, va preguntarle al List si existe, si Existe, regresa True, sino, False, y apareceran los menus cuales el usuario no tenga permiso desactivados, ademas de eso, no podra acceder via URL, si has configurado correctamente el security.xml del Spring Security.
Tags: Ajax, Java, RichFaces, spring securityRichfaces, el indicador a4j:status
Desde que existe la Web 2.0, se puso de moda usar Ajax para darle un aspecto de escritorio a nuestras aplicaciones Web, una de las mas usadas, el el LOADING AJAX, en PHP es facil con las librerias Prototype y jQuery, pero en Java es otra historia, pero no, no crean, desde que aparecio Richfaces, el gallo canta mas temprano, les presento el
a4j:status es un indicador de una petición Ajax que tiene 2 estados, iniciado y detenido. El estado de inicio indica que una peticion Ajax esta en progreso, cuando la respuesta Ajax viene de regreso corresponde el componente cambia al estado detenido.
<a4j:region id="editando"> <h:inputText value="#{userBean.name}"> <a4j:support event="onkeyup" reRender="outname" /> </h:inputText> <a4j:status for="editando" onstart="Richfaces.showModalPanel('ajaxLoadingModalBox',{width:100, top:100})" onstop="Richfaces.hideModalPanel('ajaxLoadingModalBox')"></a4j:status> </a4j:region> <rich:modalPanel id="ajaxLoadingModalBox" minHeight="100" minWidth="200" height="80" width="400" zindex="100"> <h2><h:outputText value="Validando..."> </h:outputText></h2> </rich:modalPanel>
- La propiedad for, indica con que region va a trabajar el indicador de estado, en nuestro ejemplo se llama “editando”, cuando se ejecute la peticion Ajax del inputText con el a4j:support, el buscara un indicador de estado para la región a la cual pertenece el input, este sera nuestro indicador el que sea invocado.
- Las propiedades onstart y onstop, estan encargadas de ejecutar lo que en ellas este indicadas, pueda ser un bean, o codigo JavaScript, pero en nuestro caso usamos un componente ModalPanel “ajaxLoadingModalBox”, que aparecera mientras el indicador de estado pasa de Iniciado a Detenido. Tags: Ajax, loader, RichFaces
¿Cuál es el mejor framework Ajax?
En plena fiebre 2.0 han aparecido montones de alternativas diferentes para desarrollar aplicaciones AJAX.
Suelo utilizar Java, y buscando un poco he encontrado esta comparativa de frameworks en la que se describen unos cuantos. Sinceramente, me he mareado un poco… con lo cómodo que estaba yo con Struts.
La pregunta es fácil: ¿Qué es lo que se lleva ahora? O mejor aún: ¿Qué creéis que se llevará mañana?
Tags: AjaxAJAX: El peligro de la magia
He estado leyendo esta noticia de javaHispano
en donde se habla sobre Backbase, y me ha hecho pensar en AJAX, y en
como puede ser problemático en determinados casos que explicaré a
continuación.
Antes de nada, me gustaría comentar que la demo de Backbase me ha
gustado muchísimo. Es genial ver todos esos efectos, hasta ahora
relegados al mundo del escritorio, ejecutándose en Firefox sin ningún
problema.
Desde luego, no hay una buzzword en estos meses que esté
sonando más que AJAX. El término AJAX ha aparecido de repente y ha
convertido las aplicaciones web tradicionales en RIAs (aplicaciones
ricas de Internet), incrementando la usabilidad de sus interfaces y
haciendo posible el uso de componentes hasta ahora relegados a otros
ámbitos. A pesar de que ya sabéis que era algo que existía hace tiempo,
lo cierto es que ha sido como un truco de magia, "ahora ves un pañuelo,
y ahora ves un conejo".
Pero ojo con la magia, porque siempre hay truco. Y eso es lo
que no se debe olvidar. Como sabéis, la clave en AJAX es esconder las
interacciones con el servidor, realizándolas en un modo asíncrono de
modo que el usuario no se entera de que están pasando cosas. Si a esto
le sumamos que el árbol DOM se actualiza dinámicamente, tenemos que se
solventa el problema de las molestas transiciones entre páginas. ¿Cuál
es el problema entonces, si todo es tan bonito?
El problema es que como en los trucos de magia, las cosas son de un
modo diferente al que se ve. Aunque el usuario no lo vea, por detrás se
siguen haciendo continuas llamadas a través de la red, como en las
aplicaciones web de siempre. El peligro, es que muchos desarrolladores
creo que no se están dando cuenta de esto, y están viendo a AJAX como
una solución a todos sus problemas, un nuevo paradigma de programación
que por fin ha solucionado los problemas de las aplicaciones web, y que
hará que todo y absolutamente todo sea web.
Pero señores. Cordura. La web no es
necesariamente el mejor lugar para las interfaces de usuario. Ni con
AJAX, ni sin AJAX. La web es un excepcional lugar para cierto tipo de
aplicaciones, sobre todo las que se han de distribuir a través de
Internet, las que necesitan un acceso masivo y heterogéneo de usuarios,
o para las aplicaciones que requieren una enorme ubicuidad. Y es que
tenemos ejemplos de aplicaciones web modelo de éxito como flickr,
amazon, las googles, y muchas más que se os ocurrirán…
Pero sin embargo, como decía en el párrafo anterior, hay muchos
casos en los que un interfaz web está abocado al fracaso. No voy a
entrar en las ventajas de las aplicaciones de escritorio frente a las
web, porque las tenéis en las transparencias que comentaba. En lugar de
esto lo que sí que voy a hacer es comentar un ejemplo , y que creo que es descriptivo de uno de los problemas más
importantes de las aplicaciones web, y más concretamente de AJAX. Este
problema es la necesidad de conexión de las aplicaciones web; y es un
problema de AJAX, justamente porque AJAX nos "esconde" esa necesidad,
nos "engaña" haciéndonos creer que tenemos todos los datos, y puede
hacer que los desarrolladores olviden que realmente las cosas no son
tan mágicas como parece. Muchos sabéis que trabajo en ámbitos
hospitalarios. Os voy a poner un ejemplo dentro de este mundillo:
En nuestro hospital hay muchas aplicaciones, entre las que como
comprenderéis hay algunas bastante críticas. Una de ellas es la de mi
amigo Ricardo, la de hemodinámica. Esta aplicación es utilizada por los
hemodinamistas para controlar a los pacientes que tratan. Así, cuando
un paciente por ejemplo va a ser operado, para que le hagan un
cateterismo por ejemplo, quizás por que haya sufrido algún infarto, los
hemodinamistas lo que harán será antes de nada abrir la ficha del
paciente y comprobar todos los datos: si ha tenido lesiones en las
arterias anteriormente, si se le han prácticado más cateterismos,
comprobarán los diferentes parámetros (creedme hay muchísimos) de otras
intervenciones realizadas sobre este paciente, etc. Si todo está
correcto, el paciente entra en la sala y se procede a realizar la
intervencion.
Ahora bien. Imaginaros que los hemodinamistas están ya
operando al paciente, y que de repente el responsable de la operación
ve un problema y necesita corroborar algunos datos. Entonces, ordenará
a alguno de los asistentes que vaya al ordenador a localizar los datos
que necesita. El asistente se acerca al ordenador, y recorre las
diferentes solapas de la aplicación recolectando los datos sensibles.
Una vez los va leyendo, se los va comentando al hemodinamista jefe, y
la operación continua. Si hay suerte, el paciente saldrá adelante, y
habrá un nuevo éxito.
Pénsemos en lo que podría pasar con un aplicación web con
AJAX. Desde el punto de vista del usuario, aparentemente todo es lo
mismo. A fin de cuentas, es lo que promete AJAX, mejores componentes
gráficos y transparencia en el acceso a datos. Sin embargo, la realidad
es otra. En este caso, la aplicación necesita estar conectada continuamente
a un servidor. ¿Qué sucede si en el momento en el que se necesitan los
datos se cae la red?, ¿y si se cae la base de datos?, ¿y si se estropea
el cable de red?, ¿y si se cae el servidor de aplicaciones?, ¿y si
algún técnico de sistemas se equivoca y desconecta un switch? ¿y si…?
En fin, yo creo que se os pueden ocurrir decenas y decenas de posibles
problemas que ya hemos vivido. En el caso anterior, no podría pasar
nada de esto, porque los cientos y cientos de datos ya están
precargados, y los hemodinamistas los tienen a su disposición. Sí, es
cierto que pueden pasar otras cosas, pero por lo menos hemos minimizado
enormemente el riesgo.
Ese es el peligro que yo le veo a AJAX y que nadie comenta. Todo es
muy bonito, todo es muy fantástico, todo es muy drag and drop y muy
desplegable, pero por debajo todo sigue igual, y conviene no olvidarlo,
y si no, poneros en el pellejo de la persona del caso anterior.
En ámbitos hospitalarios este tipo de casos pasan mucho. Y en otro
tipo de ámbitos también. Normalmente las aplicaciones que pueden
requerir el tratar muchos datos que ya han sido cargados, y permitir el
trabajo con ellos, están destinadas al escritorio. Esto es simplemente
porque es el mejor lugar para estas aplicaciones. Las aplicaciones web
tienen su sitio. Por ejemplo, el sistema de citas de nuestro servicio
de salud es un sistema web, cosa que es absolutamente lógica, y que es
un ejemplo de un buen lugar para un interfaz de usuario web.
Bueno creo que he soltado un buen rollo, ¿no?. Así que no sigo más.
En resumen: señores, cordura y precaución con lo que usamos, lo que
escogemos, y para qué lo escogemos. Que no todo es tan bonito como
parece, y que no existe la tecnología "única", sino muchas tecnologías
que están ahí para que las utilicemos cuando realmente se necesitan.


