Cómo-hacer...‎ > ‎

JasperReports Server CE V4.7.0 con Directorio Activo

publicado a la‎(s)‎ 22 sept. 2012 7:10 por Andrés Arenas Vélez   [ actualizado el 22 sept. 2012 7:25 ]
 

JasperReports Server es uno de mis proyectos favoritos.  Si no está familiarizado con Jasper Reports aquí va una breve descripción de lo que se trata.

Primero, está el diseñador de reportes:  iReport Designer

Con está gran herramienta se puecen crear reportes de una manesa sencilla e intuitiva.  Si ha trabajado antes con Crystal Reports o MS Access se acostumbrará fácilmente a usar está herramienta.  El resultado de su diseño será un archivo .jxml que contiene la descripción del reporte.

el vinculo entre iReport Designer y JasperReports Server es la libreria JasperReports library.  Está librería de java usa el archivo jxml para generar el reporte en varios formatos incluyendo PDF, HTML, XLS, Etc.  Genera un archivo compilado .jasper que puede ser utilizado desde cualquier aplicación java.  Yo no soy un programador de java, así que prefiero utilizar para ver mis reportes la siguiente herramienta.

El Servidor JasperReports.

Está es una aplicación web que corre en un Servidor Tomcat que funciona como un repositorio de reportes.  Los usuarios se registran en la aplicación web para ver sus reportes desde allí.  Los reportes pueden ser exportados a varios formatos e incluso puede programarse al servidor para enviarlos por correo de manera programada.  Es una poderosa y madura herramienta.

Una cosa a tener en cuenta es que estas 3 aplicaciones son proyectos separados y se mueven a diferente ritmo.  Es muy importante asegurarse que la librería utilizada en iReport sea la misma soportada por la librería en el servidor.  En el momento en que escribo esto todos los proyectos están sincronizados en la versión 4.7.0.

Así que, sea cuidadoso al actualizar iReport para descubrir que el servidor no puede correr los reportes que produce debido a nuevas e incompatibles capacidades.

La mejor parte es que estas aplicaciones son multi-plataforma así que si prefiere puede instalarlas todas o alguna en Windows o Linux y no tendrá ningún problema.

Para facilitar más las cosas, JasperReports Server puede ser instalado en un paquete que incluye su propio Tomcat + PostgreSQL así que la instalación será solo clics y listo.

Lo que to tengo es, creo yo, un escenario típico:  Windows Server + MSSQL Server, Cientes Windows y un servidor Linux para otras tareas.

JasperReports soporta la integración con DA pero debo confesar que es un poco complicado; Me tomo una semana o más lograr que todo trabajara como quería.

Asumiré que ya tiene su  JasperReports Server instalado y funcionando en este punto.  Esa parte es fácil y está muy bien documentada en el sitio del poryecto.  Está es mi cnfiguración:

Windows Server 2003
+ MSSQL 2005

Centos 6.3 Server
+ Apache Tomcat 7.029
+ PostgreSQL 9.2
+ Jasper Reports Server 4.7.0 CE

El modelo de seguridad incluido en Jasper Reports utiliza la base de datos PostgreSQL para almacenar los roles y los usuarios.  Cada elemento en el servidor puede asignar permisos a los roles.

No Access
Administer
Read Only
Read + Delete
Read + Write + Delete
Execute Only


Ej. en el  Reporte Anual ce Ventas (Sucursal 1) estos pueden ser los permisos para cada rol:

ROLE_USER        No Access
ROLE_Ventas_S1   Read Only
ROLE_Ventas_S2   No Access
ROLE_Gerencia    Administer


Un usuario puede tener uno o más roles tenienro por defecto el rol ROLE_USER.

Lo que queremos lograr en Jasper Reports es usar los usuarios del Directorio Activo para registrarnos en el servidor y usar los grupos del DA como roles para asignar los permisos.

Puede dejar el usuario por defecto jaspeadmin, o cualquier otro administrador local, para propositos de resolver problemas. El m ecanismo que usa Jasper Reports Server para integrarse con el DA trabaja asi:

□   El usuario envia las credenciales a traves de la pagina de registro usando usuario /contraseña.
□   El usuario / contraseña se verifica contra el DA y la base de datos local.
□   Si la autenticaciín es exitosa, el servidor trae los grupos a los que el usuario pertenece.
□   El servidor crea el usuario en la dase de datos local si aun no existe.
□   Todos los grupos seran creados como roles en la base de datos( grupo1 -> ROLE_grupo1 )
□   El usuario local es asignado a los correspondientes roles.

Asi que a medida que los usuarios del DA se registran el servidor llenará las tablas locales usuario, grupos y usuarios-grupo; entonces podrán asignarse los permisos de los reportes a los nuevos roles.

Yo he encontrado algunos problemas en el proceso pero luego describiré las soluciones para haceerlos funcionar como se espera.

Primero, edite el archivo applicationContext-security.xml localizado en le directorio webapps/jasperserver/WEB-INF de su instalación de Tomcat.


<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
  <property name="providers">
    <list>
       <ref local="ldapAuthenticationProvider"/>
       <ref bean="${bean.daoAuthenticationProvider}"/>
       <!--ref bean="anonymousAuthenticationProvider"/-->
       <!--ref local="jaasAuthenticationProvider"/-->
    </list>
  </property>
</bean>


Retire los comentarios del proveedor de autenticación ldap y comente el de registro anónimo.

Luego, en el mismo documento encontrará tambien comentada la sección de autenticación ldap.  Al final debe lucir como esto:


<!--   For LDAP authentication     -->

<bean id="ldapContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <constructor-arg value="ldap://192.168.5.10:389/DC=COMPANIA,DC=COM"/>
  <property name="userDn"><value>CN=administrator,CN=Users,DC=COMPANIA,DC=COM</value></property>
  <property name="password"><value>admin-password</value></property>
</bean>


<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
  <constructor-arg index="0"><value></value></constructor-arg>
  <constructor-arg index="1"><value>(sAMAccountName={0})</value></constructor-arg>
  <constructor-arg index="2"><ref local="ldapContextSource" /></constructor-arg>
  <property name="searchSubtree"><value>true</value></property>
</bean>


<bean id="ldapAuthenticationProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
  <constructor-arg>
    <bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
      <constructor-arg><ref local="ldapContextSource"/></constructor-arg>
      <property name="userSearch" ref="userSearch"/>
    </bean>
  </constructor-arg>
  <constructor-arg>
    <bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
      <constructor-arg index="0"><ref local="ldapContextSource"/></constructor-arg>
      <constructor-arg index="1"><value>OU= GRUPOS</value></constructor-arg>
      <property name="groupRoleAttribute"><value>CN</value></property>
      <property name="convertToUpperCase"><value>true</value></property>
      <property name="rolePrefix"><value>ROLE_</value></property>
      <property name="groupSearchFilter">
        <value>(&amp;(member={0})(objectclass=group)(cn=JASPER_*))</value>
      </property>
      <property name="defaultRole"><value>ROLE_USER</value></property>
      <property name="searchSubtree"><value>true</value></property>
     </bean>
  </constructor-arg>
</bean>


En el primer bean, ponga el servidor y el usuario para inspeccionar el DA.  Yo uso el administrador para evitar problemas, pero debe intentarlo con un usuario menos sensitivo cuando tenga todo trabajando bien.

Luego, queremos que los usuarios sean comparados usando el sANAccountName que es el nombre de usuario con el que el usuario se registra en el DA.  El siguiente bean busca los grupos en la unidad organizacional OU que usted especifique aquí. Yo filtro aqui los grupos qeu empiecen con JASPER_ de modo que solo esos grupos serán importados al servidor.  Me parece mejor de esa manera, como un usuario puede pertenecer a muchos grupos que no tienen nada que ver con los reportes y yo nunca usaré esos grupos para asignar permisos. Todo lo que se requiere es crear los grupos en el Directorio Activo con este prefijo y filtrarlos aquí. De esa manera, un grupo llamado JASPER_GERENCIA será creado como ROLE_JASPER_GERENCIA en el servidor.

Ahora, el último paso es permitir al servidor guardar los registros en el log para revisar que todo este bien.

Edite webapps/jasperserver/WEB-INF/log4j.properties y modifique esta línea:

   log4j.rootLogger=WARN, stdout, fileout

De esa forma Tomcat guardará datos detallados del proceso de registro.

Bien, vamos a probar.

Cree algunos grupos en su OU=GRUPOS como JASPER_VENTAS, asigne algunos usuarios y revise el resultado.  En su Tomcat logs/catalina.out encontrará algo como esto:

2012-09-21 15:46:42,572  WARN LoggerListener,http-bio-8080-exec-3:60 - Authentication event AuthenticationSuccessEvent: usuario; details: org.springframework.security.ui.WebAuthenticationDetails@1c07a: RemoteIpAddress: 192.168.5.27; SessionId: 106B002787102DD98C55A760A897CA74
2012-09-21 15:46:42,576  WARN LoggerListener,http-bio-8080-exec-3:60 - Authentication event InteractiveAuthenticationSuccessEvent: usuario; details: org.springframework.security.ui.WebAuthenticationDetails@1c07a: RemoteIpAddress: 192.168.5.27; SessionId: 106B002787102DD98C55A760A897CA74
2012-09-21 15:46:42,618  WARN UserAuthorityServiceImpl,http-bio-8080-exec-3:899 - Added following external roles to: usuario
ROLE_USER

2012-09-21 15:46:42,621  WARN UserAuthorityServiceImpl,http-bio-8080-exec-3:935 - Updated user: usuario. Roles are now:
ROLE_USER
ROLE_JASPER_VENTAS
ROLE_JASPER_GERENCIA



2012-09-21 15:46:42,653  WARN UserAuthorityServiceImpl,http-bio-8080-exec-3:941 - Updated user: usuario. Roles are now:
ROLE_USER
ROLE_JASPER_VENTAS
ROLE_JASPER_GERENCIA


Ahora los roles han sido creados.  Registrese con el administrador local y asigne a los roles creados permisos a los reportes.  A medida que los usuarios pertenecientes a estos grupos se registren serán asignados a los roles automáticamente.

Escribí un pequeño script para monitorerar los usuarios que se registran en el servidor:

#!/bin/sh
cat /usr/share/apache-tomcat-7.0.29/logs/catalina.out | grep InteractiveAuthenticationSuccessEvent | cut -d: -f1,2,3,5 | cut -d" " -f1,2,6


Este script de dos lineas listará la fecha y el usuario que se haya registrado exitosamente en el servidor.

Por último, DA no es sensitivo a mayúsculas/minúsculas, luego usuario, Usuario, UsUaRio son lo mismo para el DA; pero no para Jasper Server, así que cada vez que el usuario entra diferentes combinaciones estas serán creadas en la base de datos creando duplicados innecesarios.

Para prevenir esto, edite el archivo:

webapps/jasperserver/WEB-INF/jsp/templates/login.jsp

Cambie la linea 70:

<input id="j_username" name="j_username" type="text" style="text-transform:lowercase;" onkeyup="javascript:this.value=this.value.toLowerCase();" autocomplete="off"/>

Listo!

Espero que esto le sea de utilidad a alguien más. Disfruten!
Comments