Blog

Java security: JAAS, Apache Shiro or DIY?

Almost every application has a need for security features so it makes a lot of sense to standardize it. That is where the Java Authentication and Authorization Service (JAAS) enters the scene. However whether it is a valid choice to go with depends on your situation.

In order to deal with the security requirements of your application you have essentially three options. Use the JAAS, as part of your Java environment, choose another third party library, there are some to choose from, or, for the really brave, build it yourself. 

With the do it yourself approach, you'd better be careful. Not just because of the amount of work, but also because the demands for what proper security means have become much higher over the years. The days of just storing the two fields, username and passwords and go with that are long gone. If you make a mistake you might accidently open your application to the outside world.

You can use JAAS in a JAVA EE environment and use annotations to specify the roles that you grant access to a resource. Purely declarative, it moves out the way of your program code nicely. It is a shiny implementation of separation of concerns.
Example: In the following snippet only users that may fulfill the role of 'BusinessAdmin' are allowed to this class.

@DeclareRoles("BusinessAdmin")
public class Calculator {
  ...
}

However unfortunately there are some drawbacks. The functionality of JAAS is limited, and it depends of your application whether that might become an issue. Also, it is not entirely application server independent. In practice this may mean the end of the portability of your application from Glassfish to Wildfly, to Websphere etc. When you deliver your application to different sites or customers this is probably unacceptable. Or when you want to maintain a policy to stay vendor independent.

Storage to a file
By default user credentials (username, password, roles) are being stored to a file. Other options are supported such as LDAP-lookups or storage in a JDBC database. Storage to a file is a good way to go for the enterprise application that has a relatively small number of 'real' users - besides eventually a broader audience without user priviliges. You can manage the users from the managament console of the application server, so you don't need to bother to build a user management component yourself.  

Storage to a database
When building a public web-application where a visitor can register him or herself you often easily reach thousands of users. The obvious way then is to store the credentials in a database. You can configure JAAS to do that, but the way storage takes place, the names of tables and columns is vendor specific. Some application servers let you specify the names of the tables and the columns (Glassfish). Others, like JBoss, let you enter the necesseray SQL-queries directly. 

Another option is to make use of the pluggable architecture that application servers offer to write the connection component to the database yourself. 
An excellent tutorial is to be found here: https://www.nabisoft.com/tutorials/glassfish/securing-java-ee-6-web-applications-on-glassfish-using-jaas.
Although in itself this is quite powerful technology you might ask yourself whether you want to do this in the case of a public web-application. When looking at all requirements for a public web-application related to security JAAS in effect only covers part of it. 

As an example the list for access and security related requirements for the application I am working on:

  • authentication: are you who you say you are? (JAAS: yes)
  • authorization: are you allowed to do the things you want to? (JAAS: yes)
  • remember me: log me in automatically next time (JAAS: yes)
  • run as: an administrator can take over your account and help you
  • enable 'deep login': when you don't login on the frontpage but directly request a deep page in the site we will try to login you automatically in the background
  • evaluate password strength
  • register, change password, handle forgotten password
  • keep track: log logins
  • intrusion detection: log failed attempts to login
  • block potential intruders: block ip-addresses based on the number of failed attempts to log in within a short period of time
  • block potential intruders: block a user because of too many failed attempts originating from different ip's within a short period of time

Some of these requirements are best implemented by using filters. If you have to implement several filters already, how big is the difference to write a few filters extra and leave JAAS out?  

Of course you then will need authentication and authorization code. The first resource to look is The Open Web Application Security Project (OWASP) http://www.owasp.org. Their wiki can be quite dazzling, but it is a goldmine for all security related issues the average developer hasn't thought about. (Did you care about log injection??)

Then there is the Apache Shiro project (http://shiro.apache.org). As with other Apache projects, it is high quality, well maintained, well documented. Only it is more Java and less Java EE oriented. A background-article about how to do hashing properly with code samples can be found here: https://crackstation.net/hashing-security.htm. Another source on the OWASP site, although no longer maintained: https://www.owasp.org/index.php/Hashing_Java.
If you are looking for a library that helps your do it yourself-approach, take a look at Jasypt (http://www.jasypt.org) or BouncyCastle (http://www.bouncycastle.org). When you want to evaluate password strength  Passay (http://www.passay.org) might help you.

As always, it is easy to find code on the internet but really, check the quality before you implement it. Unless it originates from a reliable source like the Apache project I always favor to compile from inspected sources myself instead of dropping jar's that can contain anything in your application. Free software is meant to inspire not to make you lazy.

Overname alleen na voorafgaande toestemming.