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.

public class OpenIDConnectAuthModule implements ServerAuthModule, ServerAuthContext


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

public class OpenIDConnectServerAuthConfig implements ServerAuthConfig {
    private String appContext;
    private CallbackHandler handler;
    private String layer;
    private Map<String, String> options;
    public OpenIDConnectServerAuthConfig(Map<String, String> options,
        String layer,
        String appContext,
        CallbackHandler handler) {
        this.appContext = appContext;
        this.layer = layer;
        this.options = options;
        this.handler = handler;

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 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.

public String getAuthContextID(MessageInfo messageInfo) {
    Object isMandatory = messageInfo.getMap()
    if (isMandatory != null && isMandatory instanceof String && Boolean.valueOf((String) isMandatory)) {
        return messageInfo.toString();
    return null;

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.

public ServerAuthContext getAuthContext(String authContextID,
    Subject serviceSubject,
    Map properties) throws AuthException {
    Map augmentedOptions;
    if (properties == null) {
        augmentedOptions = options;
    } else {
        augmentedOptions = new ConcurrentHashMap(options);
    OpenIDConnectAuthModule module = new OpenIDConnectAuthModule();
    if (authContextID == null) {
        module.initialize(new MessagePolicy(new TargetPolicy[0], false),
        new MessagePolicy(new TargetPolicy[0], false), handler, augmentedOptions);
    } else {
        module.initialize(new MessagePolicy(new TargetPolicy[0], true),
        new MessagePolicy(new TargetPolicy[0], true), handler, augmentedOptions);


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
public class OpenIDConnectAuthModuleConfigProvider implements AuthConfigProvider {
    private final Map<String, String> options;
    public OpenIDConnectAuthModuleConfigProvider(Map<String, String> options,
        AuthConfigFactory authConfigFactory) {
        this.options = options;
    public ClientAuthConfig getClientAuthConfig(String layer,
        String appContext,
        CallbackHandler handler) throws AuthException {
        return null;
    public ServerAuthConfig getServerAuthConfig(final String layer,
        String appContext,
        CallbackHandler handler) throws AuthException {
        return new OpenIDConnectServerAuthConfig(options, layer, appContext, handler);
    public void refresh() {

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

   .registerConfigProvider(new OpenIDConnectAuthModuleConfigProvider (options, null),
    "HttpServlet", null, null);

The sources

The source code to this is available in 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


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.