Wednesday, February 4, 2015

Apache Shiro, Hibernate and Spring integration

Introduction Most real world applications require some level of security irrespective of their size and complexity. There may be administrative pages in a web application where only admins are allowed to gain access or may have some links to downloads, only a registered user can view. Since these use cases are so common among all most all applications, it makes sense to develop a common strategy to implement security in our applications. But fear not, frameworks like Apache Shiro got you covered. In the following text, we are going to configure authentication and authorization in Shiro. We'll assume our users and their roles reside in a MySql database. To that end, we'll use Hibernate to work with the database and Spring will be used to inject our DAOs. So let's get started! pom.xml file The dependencies are self explanatory. We are using commons-dbcp to configure our hibernate data source easily. web.xml file

In the web.xml file we have configured a listener as usual for spring context and filter for Shiro. What we are about concerned here is the way the filter is defined. Notice the name of the filter. That exact name is the name of the bean defined in the applicationContext.xml which we are going to create later. The DelegatingFilterProxy in Spring gets the name of the filter and finds a bean matching the name in the application context xml file. applicationContext.xml

Apart from hibernate related beans, notice the other three beans. In shiroFilter bean’s filterChainDefinitions list contains a list of URLS along with their authorized role names. For eg: admin** = authcBasic, roles[ROLE_ADMIN] says that only users having ROLE_ADMIN role can access to URLs starting with /admin. If user is not authenticated, a browser generated login dialog will be displayed (HTTP BASIC AUTHENTICATION). We are using a custom realm, so that we can use hibernate to get user accounts from the database for authentication and authorization. A realm in Shiro is a way of accessing security data. We can use an in memory database or JDBC or any other way of data retrieval method. Since we want to use hibernate we are going to need a custom Realm. Since we have our own custom relam, we have to tell Shiro’s security manager by setting the property ‘realm’ in the securityManager bean. MyRealm.java

Hibernate entity clases: Users.java and UserRole.java





Note If your passwords are hashed in your database then, you might want to implement your own password matcher and change credentialsMatcher to your implementation in your custom realm as follows. Notice we have defined this bean via annotations. MyMatcher.java


Now update your realm bean configuration to refer to custom password matcher: applicationContext.xml


Saturday, January 24, 2015

Dealing with welcome files in struts 2

Usually we want our users to direct to index.jsp file, or whatever the name of the homepage file, when they key in just the domain name of ours in their browser. This can be simply done by specifying a welcome file list in the deployment descriptor of our java web application. But things get more complicated when you are using struts tags on one of the welcome files. Assume your struts filter is specified by extension mapping as follows.

Now only URIs that end with “*.html” will go through the struts’ servlet filter. Now assume your index file is a jsp called, well index.jsp. So your welcome file list should be something like this.

This configuration works as long as you don't have any struts tags in the index.jsp file. But whenever you put struts tags, the index.jsp file must be accessed by going through the struts servlet filter. Otherwise, following error will pop out.

org.apache.jasper.JasperException: The Struts dispatcher cannot be found.  This is usually caused by using Struts tags without the associated filter.
So we need to do following changes to make our welcome files go through struts.
  1. Change the welcome files list to the following <welcome-file>index.html</welcome-file>
  2. Create an empty file called html in the web root
  3. Specify an action for index.jsp in the struts.xml file