This is a blog about the projects or other things that I am currently working on.  With a little luck you will find some useful information here.  Enjoy!

JasperReports Server CE V4.7.0 with Active Directory

posted Sep 21, 2012, 2:04 PM by Andrés Arenas Vélez   [ updated Sep 22, 2012, 7:26 AM ]

 
 JasperReports Server is one of my favorite projects.  If you are not familiar with Jasper Reports I will give a short description of what this is all about.

First, it is the report designer:  iReport Designer

With this great program you can create reports in a friendly and fairly intuitive way.  If you have used Crystal Reports or MS Access reports in the past you will get used to this tool easily.  The result of your design will be a .jxml file with the report description.

The link between iReport Designer and JasperReports Server is the JasperReports library.  This java library uses the jxml file to render the report to various formats including PDF, HTML, XLS, Etc.  It generates a complied file .jasper that can be used in any java application.  I’m really not a java programmer, so I prefer to view my reports on the next tool.

The JasperReports Server.

This is a java web application running on a Tomcat Server that works as a repository of reports.  Users login on the web application to see their reports from there.  Reports can be exported to various formats and you can even make the server to mail the reports on a schedule.  It is a very powerful and mature application.

One thing to have in mind is that these 3 applications are separate projects and they move at different paces.  It is very important to make sure that the library used in iReport is the same supported library on the server.  At the moment of this writing all projects are in sync in version 4.7.0.

So, be careful upgrading iReport to find out your server cannot display the reports it produces due to new incompatible features.

The great part is that all these applications are cross-platform so if you prefer to install all or some of them on Windows or Linux you will have no problems.

To make things easier, JasperReports Server can be installed as a bundle with its own Tomcat + PostgreSQL included in the installation package so it will make it a click and go setup.

What I have is, I think is, a typical scenario:  Windows Server + MSSQL Server, Windows Clients and a Linux Server for other tasks.

JasperReports support AD integration but I must confess it’s a little tricky; I spent like a week or more to get this working the way I wanted.

I will assume you have your JasperReports Server up and running at this point.  That part is easy and well documented on the project site.  This is my setup:

Windows Server 2003
+ MSSQL 2005

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

The build-in security model in Jasper Reports uses the PostgreSQL database to store the roles and the users.  Every element on the server can assign specific permission to the roles.

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


Ex. On the Annual Sales (Branch 1)  report these could be the permissions to each role:

ROLE_USER        No Access
ROLE_Sales_B1    Read Only
ROLE_Sales_B2    No Access
ROLE_Management  Administer


A user can have one or more roles at a time having by default ROLE_USER.

What we want to accomplish is Jasper Reports using the users from Active Directory to authenticate against the server and use AD Groups as roles to assign the permissions.

You can leave the default jaspeadmin user, or any other local admin user, for troubleshooting purposes. The mechanism Jasper Reports Server uses to integrate with AD works like this:

□    The user send credentials on the login page using a username / password combination
□    The username / password combination is verified against AD and the local database.
□    If the authentication is successful, the server will retrieve the groups the user belongs to
□    The server will create the user on the local database if its not created already
□    All the groups will be created as roles on the local databases ( group1 -> ROLE_group1 )
□    The local user will be assigned to the corresponding roles

So as AD users start to login on the server it will populate the local users,roles and user-role tables; then you can use those roles to assign permissions to the reports.

I found some glitches on the process but I’m going to describe the solutions to have it working as you expect.

First, edit the applicationContext-security.xml file located on the webapps/jasperserver/WEB-INF directory of your tomcat installation.


<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>


Uncomment the ldap authentication provider and comment the anonymous login.

Next, on the same document you will find also commented a section for ldap authentication.  It should end looking like this:


<!--   For LDAP authentication     -->

<bean id="ldapContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <constructor-arg value="ldap://192.168.5.10:389/DC=COMPANY,DC=COM"/>
  <property name="userDn"><value>CN=administrator,CN=Users,DC=COMPANY,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= GROUPS</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>


On the first bean, put the server and the user to browse the AD.  I use administrator to avoid issues, but you better try with a less sensitive user when you get things working.

Next, we want the users be mapped using the sANAccountName which is the short user login name on AD.  The next bean will search for the groups on the OU you specify here.  I filter here the groups beginning with JASPER_ so only those groups are going to be imported to the server.  I found it better that way, since a user can belong to a lot of groups that have noting to do with the reports and I will never use those group to assign permissions.  All you need to do is to create your groups on the Active Directory with this prefix and filter them here. That way, a group called JASPER_MANAGEMENT will be created as ROLE_JASPER_MANAGEMENT on the server.

Now, the last step is to allow the server to log the logins to check everything is OK.

Edit webapps/jasperserver/WEB-INF/log4j.properties and modify this line:

   log4j.rootLogger=WARN, stdout, fileout

That way on the tomcat log it will have detailed data on the login process.

Well, let’s test test it.

Create some groups on your OU=GROUPS like JASPER_SALES, assign some users to the group and check the results.  On your tomcat logs/catalina.out you should see something like this:

2012-09-21 15:46:42,572  WARN LoggerListener,http-bio-8080-exec-3:60 - Authentication event AuthenticationSuccessEvent: username; 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: username; 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: username
ROLE_USER

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



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


Now the roles are created.  Login with the local admin and give the created roles permissions to the reports.  As other users belonging to those groups login in the future they will be added automatically.

I wrote a little script to check when user login to the server:

#!/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


This two lines script will list the date/time and the user that successfully logged on the server.

Finally, AD is not case sensitive, so user, User, UsEr are all the same to AD; but not for Jasper Server, so every time the user enters the name in different caps those users will be added creating duplicates on the local database.

To prevent this, edit the file:

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

Change line 70:

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

That's it!

Hope this helps someone out there. Enjoy!

Improve your Raw photos with UFRaw and Gimp

posted Jul 25, 2010, 11:12 AM by Andrés Arenas Vélez   [ updated Sep 22, 2012, 7:19 AM ]

My Canon EOS takes very good photos, but as an amateur photographer I not always take the best pictures at the first shot.  Specially problematic is getting the right exposure on every shot, so that is why I prefer to save my photos in Raw format for later processing and retouching.

I am going to describe the basic work flow I use to get the most of my raw photos using two great tools UFRaw + GIMP.

Both tools are available for Windows and Linux.  Since my base distro is Fedora, this is how you can get them both from the standard repositories using yum as root:

yum -y install gimp ufraw ufraw-gimp

Those are the minimum packages you will require, and yum will install all the dependency packages required.  I would recommend installing the help files and the extra tools.

yum -y install gimp-help gimp-help-browser gimp-data-extras gimpfx-foundry

Now let's start loading the photo with UFRaw.  Locate the raw image and right click on it selecting Open with UFRaw.

UFRaw will let you adjust a lot of parameters on your photograph before exporting it to Gimp, but we will focus here in the exposure.  The original exposure is 0.00.  Click on the gears icon and the exposure will be auto-corrected to average the tones on your photo.




Check the Live Histogram, now is normalized.  UFRaw chose -0.28 as the average exposure value.

This is going to be the base exposure for the final photo.  I will generate 3 photos from here, one underexposed, one neutral and one overexposed.
 
Photo              Exposure
Background         -0.28
Underexposed (D)   -2.28 (Background - 2 )
Overexposed  (L)    1.72 (Background + 2 )

To export the photo to Gimp, set the desire exposure and click on the Gimp Icon on the bottom-right corner.  Gimp will open a new window with the photo, preserving all the Exif information of the original.

Repeat the procedure to obtain the three required photos in Gimp.



Now, we want the three photos as layers to work on them as one.  Pick the Underexposed (Dark) photo and go to the Edit menu, then  Copy Visible.  Now go to the Standard exposed picture and select on the Edit menu, Paste as > New Layer.  Repeat the procedure with the Overexposed (Light) photo and finally close them as they are not needed any more.  You should have them all on the same window as layers like this:


I renamed the layers, and this is the order I want them to be.

Now, let's create a layer mask on the Light Layer.  Right click on the layer name and select Add Layer Mask.


Select Grayscale copy of the layer and be sure the Invert mask selector is checked.
Repeat the operation with the Dark Layer, but DO NOT invert the mask.

Now, with both layers with their masks, let's Blur the masks to improve the result.  Select the Light mask and go to the Filters menu / Blur / Gaussian blur...


I usually select around 15-20 on the Blur Radius.  Apply the blur also to the Dark Mask Layer.

Finally, for better results, select the opacity of the Light layer.  I Usually select between 50-70 depending on the picture.


At this point you can save the image using Gimp's xcf extension to preserve the layers and make corrections in the future. 

To export the picture to your preferred format, first merge the layers, right-clicking on any layer and selecting Flatten image.

To go one step further I rotated the image a little using the rotating tool and crop to get the best picture possible.   Let's compare the original with the final version.


You can see the improvement on the dark areas (on the stairs) and the light areas (on the roof) and the mid-tone shadows (on the chairs).

Shooting Raw photos increase the chances to obtain good photos in the end, and with tools like these and a little patience you will obtain great results.



KeePassX + DropBox + PortableApps = Safe Passwords

posted Jul 16, 2010, 12:50 PM by Andrés Arenas Vélez   [ updated Sep 22, 2012, 7:20 AM ]

Creating useful passwords is a hard task.  To make them secure they should be long and complex enough to support guessing, dictionary or other forms of brute force attacks. On the other hand, long or too cryptic passwords are difficult to remember, so most people end writing them down, or using the same simple password everywhere.

Another issue are user names;  every website and service use different user names and that can also become very difficult to track.

To solve this in a safe way there is a great Linux application called KeePassX (see KeePass for other platforms).


keepassx-screenshot

KeePassX use a database to store your user names and passwords in a single file.  That file is encrypted with a Master Password, which will be the only password you will need to remember in the future. 

KeePassX has all the tools you need to organize and keep track of your services, user names and passwords.  The Password Generator will create for you random passwords with the specified characteristic, could it be just numbers, or combination of numbers + Symbols + Uppercase + Lowercase.  For details check the project site, it is very easy to use and I’m sure in minutes you will start loving it.

Great! But… now we have two new problems:

1. We need KeePass(X) available all the time to have access to the passwords.
2. We have to keep the database file as safe as possible.  We can not afford to loose it!

The first problem is solved by another great product called PortableApps.  There is a KeePass Portable that I have installed on my memory stick so I can run it safely on any Windows Machine out there.  That’s the magic of PortableApps, check the site for details.

The second problem is solved by DropBox.  On my Laptop I keep the database file on the DropBox folder, so it is automatically backed up to the internet when I am online and every time I make a change on it.  DropBox will keep a copy of the file and even better will keep the different the versions as I keep updating it.  If I change the file by deleting an entry, or modifying one password by mistake, I can go to the DropBox site and recover previous versions.  Even if I delete the file by mistake, I can get the last saved version from the Internet.  There is also the copy on the memory stick, which I have to update manually, from the laptop, or from the site, so all the time I have 3 copies of the file. 

That is safe enough for me, and now I can even change the password often as recommended everywhere and not worry about forgetting them anymore.


1-3 of 3