Creating a simple JASPIC auth module

One of the problems I have with several web frameworks or even tools that I have used such as Sonar and Jenkins is that they deemed it necessary to develop their own authentication system or use frameworks such as Apache Shiro, Acegi/Spring Security and the ilk as they put authentication responsibility in the hands of the application rather than the container.

Granted the typical container managed authentication is very limited to whatever the container vendor provided or having proprietary extensions such as WebSphere’s Trust Association Interceptors (TAI). Since Java EE 6, a standard way of building this has been created called Java Authentication Service Provider Interface for Containers (JASPIC). This blog post talks about creating a simple JASPIC ServerAuthModule that will use HTTP Headers to contain the authentication data much like SiteMinder does.

Some reverse proxy servers when used with client authentication such as site minder or in my intranet I have Apache using Client Side SSL certificates which pass the certificate user’s e-mail address as the user name in an HTTP Header. This allows me to pass the username to applications such as Jenkins (Reverse Proxy Auth Plugin, Redmine (HTTP Authentication Plugin) and Sonar (Reverse Proxy Authenticator).

Since I did create my own plugin that would do it for one product, namely the Reverse Proxy Authenticator plugin for Sonar I decided I should do one for Glassfish using a hardcoded header that can easily be placed as an option but kept off to keep things simple.   Without further adieu the code where I added comments to explain how JASPIC works:

That’s about it code wise. Now to deploy it is container specific, in Glassfish’s case we place it in the lib folder and refer to it in the Message Security section of the server-config as another provider (I may detail the steps for this in a future blog post).

NOTE: In terms of making it work with the application, one thing to watch out for is the groups returned by the module is not mapped to the application roles by default. Unfortunately the mapping at the moment is container specific in Glassfish’s case I create a WEB-INF/glassfish-web.xml to do the mapping as follows:

Other application servers would have their own descriptor or can be configured during deployment like in WebSphere.

Hopefully with this, we can avoid making the applications more complicated by pushing the authentication outside of the application and giving it to the container. It will make a better user experience as well as you can have single sign-on (not just keeping the passwords in sync with LDAP).

A github project with this and OAuth 2.0 Login with OpenID Connect Discovery (used by Google) will be coming when I make the time to push it up. However, feel free to use the code above.