Implementing JASPIC in the application

One of the nice things about JASPIC is it does not have to be limited to just a container installation, but can be put as part of the application.  One of the key advantages of this over web tier solutions such as Shiro-Web is the authentication subject can be passed all the way down to the EJB tier via @Inject Principal .

However to do this is a bit tricky, JASPIC isn’t really as straight forward and one key information is buried deep inside the specs and not immediately visible in the Javadocs.

This blog post assumes the reader to have gone through the motions of creating a ServerAuthModule.  The purpose of this is to somehow call the initialize() method with the settings.

When to use this

Normally I would advocate authentication be done in the container and not be part of the application.  However, there’s a specific scenario I had which forced me to do this:  I had a to use a different Server Auth Module on a server that already has the Server Auth Module defined.  So I had to do it on a per application basis.

The approach

We’re going to do a bottom up approach from the ServerAuthModule.  To start we add the ServerAuthContext  to the implements list  of the ServerAuthModule.  Since ServerAuthContext has a subset of methods as ServerAuthModule, it is not related as such it needs to be explicitly added.

ServerAuthConfig

The next bit is to create a class that implements ServerAuthConfig that will create an instance of the ServerAuthModule, intialize it and return it.

In that module is a method that determines whether the module is needed by the security constraints.  This is the one that took a while to find and it was actually in the spec.  There’s a property called javax.security.auth.message.MessagePolicy.isMandatory which is set to the string “true” if the requested resource requires authentication.  It should return null if the resource does not require any authentication.

The getAuthContext method is needed to provide the ServerAuthContext which would the initialized ServerAuthModule.  It takes in a properties map which contains additional properties that the container may send and should augment any configuration options that were passed in.  Also depending on the authContextID parameter being null or not will determine whether we initialize with a MessagePolicy indicating mandatory or not.

AuthConfigProvider

The next JASPIC component that needs to get built is used to provide the ServerAuthConfig.

  • It needs a two argument constructor though the AuthConfigFactory parameter is generally ignored.
  • The getClientAuthConfig method returns null unless a client authentication module is being provided
  • Lastly the getServerAuthConfig simply creates  a new instance of the ServerAuthConfig passing in some contextual information

Tying it to the application

To tie this to the application, the AuthConfigProvider needs to be registered in the factory as part of application startup.    To do this, a ServletContextListener is used and the contextInitialize method would set the options and register the provider using

The sources

The source code to this is available in github.com/trajano/server-auth-modules along with my OpenID Connect, Google and HTTP Header auth modules.

However, the OpenID Connect capability of server-auth-modules is deprecated in favor of a complete OpenID Connect implementation which includes the server auth module and the server side code as well in github.com/trajano/openid-connect.

Conclusion

When I worked with Java EE, I see the elegance of having the application not deal with user authentication and let the container manage it.  It is very rare that I see it in practice though because FORM authentication is quite limited and I have been in a lot of projects where I had to deal with the login use case in non-standard ways which only keep the authentication details on the web tier only.

With the advent of JASPIC, I am able to use standardized mechanisms that allow me to retrieve authentication and authorization contexts all the way through to the EJB tier.

And although this is part of the application, it can be modularized away to a different web application context if needed.