Integrating Jasper Server CE with Spring Web App

Arun Varghese
9 min readMay 1, 2018

Jasper Server reporting is a server based solution for creating, hosting and running reports. The community edition of Jasper Report Server offers a host of features that enable rapid development and deployment of reports. We started integrating Jasper Server 6.5.1 in our existing Spring MVC project about a month back and was faced with the following challenges:

  • Configure Jasper server for external database authentication with the existing PostgreSQL back end.
  • Customize reports content based on the logged in user context without passing any user related parameters to the report
  • Integrate Jasper server authentication process with Spring Web App login process at server side

In this blog , I will walk through the various configurations and code changes that were needed to achieve the above requirements. Before proceeding I would like to point out the fact that my approach is just one way to address these challenges. And better ideas and improvisations are always welcome from my dear readers.

Task-1: Configure Jasper server to use external authentication with existing PostgresSQL backend

Our initial starting point was to learn about the external authentication configuration in Jasper Reports server. The ideal place to learn about external authentication is the JasperReports Server Authentication Cookbook available for download from Jasper Reports community site. In the book, Chapter-5 provides instructions for performing external authentication and authorization using tables in an external database. The figure below gives and overview of the basic external authentication scenario.

The above figure shows a classical external database authentication scenario where the user supplied credentials are authenticated against an external DB configured. After successful authentication, the user details and roles are synchronized with the Jasper internal DB.

Our PostgresSQL DB has the users table configured to work with Spring Security in my web app. The roles for the users are stored in the user_roles table. The sample-ApplicationContext-externalAuth-db.xml file available at <Jasper-Installation-Directory>/samples folder is the configuration template for Jasper server external authentication. A copy of this file must be made and modified to match the external authentication requirements.

The first change was to disable the password validator configurations since I was planning to use plain password validation. Wait…what? Is it really secure to use plain password for authenticating with Jasper Server? It was fine in our case since the we were planning to configure authentication at the server side. Yes we are totally going to avoid the client side authentication where the username and password are sent in the URL to Jasper Server for authentication. In due course, I shall explain how this is done. The following lines must be commented to disable password validation:

In the next step we need to modify two properties: usersByUsernameQuery and authoritiesByUsernameQuery. The usersByUsernameQuery must have the select query to select the username and password from your external database. In my case, the password was encrypted using bcrypt. Since I never configured any password validator, the bcrypt encrypted password string itself is treated as password by Jasper Server during authentication. I really never bothered to validate my bcrypt password by configuring a BCryptPasswordEncoder since the password security was not a concern here. You need to configure a proper password validator if the your situation demand so.

The authoritiesByUsernameQuery must have the query to identify the role of a user. In my scenario, I created three new roles (JASPER_ADMIN, JASPER_MANAGER, JASPER_USER) in my external DB exclusively for Jasper report server. The authoritiesByUsernameQuery ensured that only jasper related roles are retrieved from external DB. Another way of doing this is by configuring mapping for external DB roles with Jasper internal roles. We are skipping it to keep things simple :)

The external data source is the database connection to use for external authentication. Provide the JDBC driver, DB URL, username and password in this configuration.

After making the changes in configuration, the configuration file must be copied to the <js-webapp>/WEB-INF folder and rename as sample-applicationContext-externalAuth-db-mt.xml

Now restart the Jasper server instance for the external authentication settings to take effect. To verify the external authentication, identify a username and encrypted password from the user table and use it to login into jasper server. If the query and data source configurations are correct, the login will succeed. The next thing to verify is whether the role is correctly assigned for the user in Jasper server. To verify the roles assignment, login to Jasper Server as jasperadmin and open the users list (Manage>Users). Click on any external username and verify that the external role name assigned is shown under Assigned Roles section.

Manage Users

At this point the first task is complete. The next task is to develop a sample report for externally authenticated user by making use of the user role and the user context.

Task-2: Develop report to use the logged in user context

A report developed and deployed in Jasper server must be authorized based on the external roles configured. And the report must be developed in such a way that context sensitive authorization is enabled. The purpose of this task is to implement the external authentication in the following two aspects:

  1. To restrict access to a report based on the externally defined role. For example, the report intended for the role JASPER_MANAGER must not be accessed by the user with role JASPER_USER.
  2. To internally bind the username of the logged in user as a hidden parameter in the report to enable context sensitive authorization. For example the user A shall view all the authorized reports in the context of that user without passing username parameter to Jasper report. The context-sensitive authorization avoids the use of username as an explicit parameter in the report. Without proper context-sensitive authorization, user B can access the report of user A by modifying the username parameter.

Role-based Authorization

Role based authorization can be configured very easily in Jasper Report Server. Login to Jasper Server as jasperadmin user and navigate to the reports folder.

As you can see, I have created three separate folders for user, manager and admin reports. Now the folders must be role authorized using the external roles from my application DB. The external roles will be synchronized in Jasper server once you complete successful login of external users. Right click on the User Reports folder and click on Permissions.

Grant Read Only access to JASPER_USER role and Non Access (default) for other roles. At this point, the reports published in User Report folder will be accessible only to the users with JASPER_USER role. Repeat this for the other two roles to complete basic role authorization configuration.

Context sensitive Authorization

The context sensitive authorization ensures that a user only sees the report data specific to the context of that user. It is the responsibility of report developer to ensure that context sensitive authorization is used for every report intended for a role where there are multiple user specific contexts.

The context-sensitive authorization can be achieved with the use of Jasper Report Server built-in parameters. In our case, the report user context could be determined using the LoggedInUsername parameter. Hence LoggedInUsername parameter was used directly in the reports. To add Jasper Report Server built-in parameters in Jasper Studio, right click on the Parameters node in the Outline area and click on Create Parameter Set.

Now select Jasper Server built in parameters and click Finish button to add all the built in parameters to the parameter list.

Now for context-sensitive authorization, we made it a practice to use $P{LoggedInUsername} in all our reports which required user context sensitive authorization.

Task-3: Integrate Jasper server authentication in Spring Web App

The last and most important task was to integrate Jasper server reports with our existing Spring MVC web app. I tried googling for how this could be achieved. And the following types of solutions were found:

  1. Use Jasper REST APIs for URL based authentication from client side to receive the authentication cookie. This involved passing the username and password in the client request. The report was then viewed in the Jasper Flow UI or by consuming the Jasper REST APIs.
  2. The alternate solution was to consume the login REST APIs from server side by passing the username and password (more secure) followed by fetching the report from the server. The report in specific format (PDF/XLS) was then transferred back to client side.

The second method was better than the first one, but we did not use it due to two reasons. Firstly, all the reports must to be requested by the web server before delivering to the client. This resulted in additional load on the web application server. Secondly, we could not integrate the Jasper flow interface which required client side authentication and cookie.

The Solution

The approach to solve this problem involved the following process for authentication and report generation:

  1. Integrate the Jasper server REST login API request into the WebAuthenticationSuccessHandler after successful Spring Security login
  2. After successful login, the cookie received in the response is saved in the user context and also send along to the home page
  3. Invoke the Jasper report flow URL from the client side to view the report which makes use of the Jasper cookie in the client browser
  4. Logout from Jasper server when the user logs out from the Spring Web app by wiring the Jasper logout REST API call

The WebAuthenticationSuccessHandler has the handle() method where the Jasper server authentication is implemented.

The Spring RestTemplate is used as the REST client to login to Jasper Server using basic HTTP Authentication. The HTTP Cookie from the response is parsed from the Jasper server response headers. The cookie is then set to the login response. This will set the cookie in the client browser which makes the client ready for any report request to the Jasper flow URL. A sample Jasper Flow URL for report is given below:

http://<web-app-domain>/jasperserver/flow.html?_flowId=viewReportFlow&_flowId=viewReportFlow&reportUnit=/reports/User/SampleReport&decorate=no

Reverse Proxy Configuration

The Jasper Server and Web app server usually runs in two separate domains. To support cookie based authentication in browser, the domain in the report URL must be same as the the domain in the Jasper HTTP cookie. The above code will fail to work if Jasper Server and the Web app are in separate domains. To solve this problem, we need to create a reverse proxy configuration in the web application server. More information on reverse proxy is available here.

The logout event handler must include a call to the Jasper Server logout API to logout the user from the web app. The code snippet for logout is given below:

Final Thoughts

The Jasper server authentication integration explained above provided secure external authentication, external role authorization and the methodology for implementing context sensitive authorization in our web app. And this resulted in a seamless integration of our web app with the Jasper flow based report viewer.

Using a single sign on technology based on CAS can further simplify the above solution.

PS:- I am not enrolled in Medium Partner Program to make money from the article. If you find the content useful, your claps will be an encouragement for more articles to follow.

--

--