Create a Java-based Liberator Permissioning Service blade

Here we explain how to create a simple Permissioning Service blade for Liberator, where the Liberator’s custom auth module is written in the Java programming language. The core of Liberator is written in C, so to create an auth module in Java, you use Liberator’s Authentication Java API.

This page explains one way to set up Liberator Permissioning. Caplin also provides a sophisticated permissioning model and tools to create a flexible permissioning system based on that model. You develop a Permissioning Adapter using the Permissioning Integration API of the Caplin Integration Suite. The resulting blade also includes a Permissioning Auth Module within Liberator that can accept permissioning data sent to it from the Adapter. For more about this, see the online documentation Permissioning Concepts.

Before you start

This example shows how to create a very simple Java-based Service blade called PermissioningJavaBlade. We’ll use as a template the JavaOpenPermissioning blade that’s built in to the Deployment Framework.

You’ll need a Liberator to help test your Service blade while you develop it. If a Liberator isn’t already deployed on a machine for this purpose, you’ll need to deploy one to the Deployment Framework on your development machine. To do this, follow the instructions in How can I…​ Deploy Platform components to the Framework. You won’t need to set up HTTPS connections or KeyMaster while you’re developing the blade, so you can ignore the topics about those things.

Make sure that your Liberator licence allows access to Liberator’s javaauth authentication module.

(The trial licence supplied with Liberator doesn’t allow you use javaauth. To see whether or not javaauth is licenced, deactivate the Liberator’s built-in OpenPermissioning blade, activate its JavaOpenPermissioning blade, and then start the Liberator. If javaauth isn’t licenced, Liberator reports "rttpd: Cannot load module javaauth - error not licenced".

In the following steps you’ll be using the dfw command of the Deployment Framework. Before entering any dfw command as ./dfw <command-name>, make sure your current (working) directory is set to the Deployment Framework’s topmost directory.

For a list of dfw commands, click here.

Blade structure

What’s in a Java Permissioning Service blade? Assuming the blade is located in in the Deployment Framework at <Framework-root>/kits/<blade_name>/<blade_name>/, relative to this path:

  • the blade compatibility information is in the control file

  • the blade’s field definitions are in blade_config/fields.conf

  • Liberator related configuration for the blade is in Liberator/etc/rttpd.conf

  • The Liberator Java auth module’s JAR file, compiled from the Java source file, is in Liberator/lib/java

Create the blade’s directory structure

  1. In a directory that’s outside the Deployment Framework (say Temp_Java_blade), make a copy of the JavaOpenPermissioning blade’s directory structure - the directory JavaOpenPermissioning within <Framework-root>/kits/and everything within it.

  2. Rename the copy of the JavaOpenPermissioning directory in Temp_Java_blade to your new blade name: PermissioningJavaBlade

Update Liberator’s configuration

A blade has to include configuration for the core Platform components that it interacts with. In this case, the core component is just Liberator, which houses the Java auth module. Configuration for this module is located in the java.conf and javaauth.conf files

Edit java.conf

Using a suitable text editor, edit java.conf in Temp_Java_blade/PermissioningJavaBlade/Liberator/etc/

  1. Change the descriptive comment at the top of the file from this:

    #
    # Liberator Java configuration for Open permissioning authentication
    # module
    #

    to this:

    #
    # Liberator Java configuration for PermissioningJavaBlade.
    #

    The file has a warning comment at the top:

    #
    # DO NOT EDIT THIS FILE !!!
    #
    #
    # If you need to change any Java configuration, do so by updating
    #
    #    global_config/environment.conf
    #    global_config/overrides/servers/Liberator/etc/java.conf
    # ...

    You can ignore this warning, because it only applies to the original file used by the JavaOpenPermissioning blade. You’ve taken a copy for use with the new blade, and during the development of the blade you obviously need to change the file!

    The existing java.conf configuration looks like this:

    jvm-location ${JVM_LOCATION}
    
    # JARs required in the startup global classpath for the JVM
    #
    jvm-global-classpath    %r/lib/java/javaauth.jar
    
    add-javaclass
       class-name   examples.OpenAuthenticator
       class-id     authenticator
       classpath    %r/lib/java/javaauth-examples.jar
    end-javaclass
  2. Change the class-name option of add-javaclass to the fully qualified name of the Java class that implements the new blade’s Java auth module:

    add-javaclass
       class-name example.permissioning.SimplePermissioning
       ...
  3. Change the classpath option of add-javaclass to point at the JAR that will contain the compiled Java code for the new Java auth module. In this example, the JAR has the name of the blade:

    add-javaclass
       ...
       classpath    "${ccd}/../lib/java/SimplePermissioning.jar"
       ...

Edit javaauth.conf

Using a suitable text editor, edit javaauth.conf in Temp_Java_blade/PermissioningJavaBlade/Liberator/etc/

  1. Change the descriptive comment at the top of the file from this:

    #
    # Permissioning authentication module Liberator Java auth configuration.
    #

    to this:

    #
    # Liberator Java auth configuration for PermissioningJavaBlade.
    #

    The file has a warning comment at the top:

    #
    # DO NOT EDIT THIS FILE !!!
    #
    #
    # If you need to change any Java configuration, do so by updating
    #
    #    global_config/environment.conf
    #    global_config/overrides/servers/Liberator/etc/java.conf
    # ...

    As for java.conf, you can ignore the DO NOT EDIT THIS FILE !!! warning.

    The existing javaauth.conf configuration looks like this:

    ###########################################################
    #
    #  Debug level - DEBUG,INFO,WARN,NOTIFY,ERROR,CRIT
    #
    ###########################################################
    log-level     INFO
    
    ###########################################################
    #
    #  Identifier for which class to load
    #
    ###########################################################
    
    javaauth-classid    authenticator
    
    #
    # Include override configuration..
    #
    include-file "${BASE}/global_config/overrides/JavaOpenPermissioning/Liberator/etc/javaauth.conf"
  2. Change the include-file item’s pathname to refer to the name of your new blade. This entry allows you to override the blade’s standard configuration after it has been deployed, by putting a different javaauth.conf configuration file in the Deployment Framework’s overrides directory for the blade (for example, you might do this to temporarily change the log-level for the blade).

    #
    # Include override configuration..
    #
    include-file "${BASE}/global_config/overrides/PermissioningJavaBlade/Liberator/etc/javaauth.conf"

    However, Liberator won’t start if this alternative configuration file is specified here but is not present in the target directory. (If you do actually want to overrride the standard configuration some time later, you can uncomment the line.)

  3. Create a text file called javaauth.conf in <Framework-root>/global_config/overrides/PermissioningJavaBlade/Liberator/etc/ This is a placeholder for overrides to the configuration in the blade’s javaauth.conf (see above), which ensures that when Liberator starts up, it won’t report that the overrides file is missing.

    #
    # Placeholder for overrides to the PermissioningJavaBlade's javaauth configuration.
    #

Edit rttpd.conf

The only thing you need to change in the new blade’s Liberator configuration file, rttpd.conf, is the descriptive comment at the top:

#
# Liberator configuration for PermissioningJavaBlade.
#

(Note that the setting of the auth-module configuration item in this file must remains as javaauth)

Update the blade control file

The Deployment Framework has two built-in Permissioning Service blades – OpenPermissioning and the JavaOpenPermissioning (the blade which we are using as our template for this example) – but only one Permissioning Service blades can be active at a time. You let the Deployment Framework know about such a potential conflict by adding an entry to the blade control file located in the root directory of the blade.

  1. Open the text file called control in Temp_Java_blade/PermissioningJavaBlade/ for edit. This is the blade control file, which should contain the single line:

    Conflicts: OpenPermissioning PermissioningService

    Change this line to:

    Conflicts: OpenPermissioning JavaOpenPermissioning
    For more about blade compatibility and dependencies, see the Reference information about the blade control file.

That’s all the configuration changes you need for the time being.

Integrate the configuration with the Deployment Framework

Now you’ve created the initial configuration for the core components that use your Liberator Permissioning Service blade, you can deploy this configuration in your development environment.

  1. ZIP up the blade directory structure in your temporary work area into a skeleton blade kit, The .zip file must have a name of the form <blade_name>-<version_number>.zip

    The topmost directory in the .zip file must be the top level directory of the blade.

    So in our example:

    The .zip filename is PermissioningJavaBlade-<version_number>.zip (say PermissioningJavaBlade-000001.zip),

    The topmost directory in the .zip file is PermissioningJavaBlade.

  2. Navigate to <Framework-root> and deactivate the existing built-in Permissioning Service blades:

    ./dfw deactivate OpenPermissioning JavaOpenPermissioning
    You can first check the activation status of these blades by running ./dfw versions
  3. Navigate to <Framework-root> and deploy the skeleton blade kit:

    ./dfw deploy ../Temp_Java_blade/PermissioningJavaBlade-000001.zip

    The ./dfw deploy command should respond with:

    Boot-strapping the Deployment Framework
    
       Unpacking PermissioningJavaBlade kit PermissioningJavaBlade-000001.zip
       PermissioningJavaBlade-000001.zip successfully unpacked and stored in kits/archive
    
       Activating PermissioningJavaBlade
    
       Blades ok

    And then ./dfw versions should show the new blade:

    Deployment Framework           6.0.4-267113
    
       Core components                Version
       -----------------------------------------------------------
       Liberator                      6.1.0-275608
       Transformer                    6.1.0-275716
    
       Deployed blades                Version            State
       -----------------------------------------------------------
       PricingAdapter                 2013.09.27.1138    Active
       PermissioningJavaBlade                            Active
    
       Built-in blades                                   State
       -----------------------------------------------------------
       BlotterExport                                     Inactive
       DemoDataSource                                    Inactive
       DirectConnection                                  Active
       HTTP                                              Active
       HTTPS                                             Inactive
       JavaOpenPermissioning                             Inactive
       LiberatorJMX                                      Active
       LiberatorWebsite                                  Active
       MinimalLiberatorWebsite                           Inactive
       OpenPermissioning                                 Inactive
       ServerIdentification                              Active
       TransformerJMX                                    Active

Note that deploying the skeleton PermissioningJavaBlade has automatically put it in the active state.

Write the Java auth module

This is the functional part of the Permissioniong Service blade that defines the actions you need it to perform. In this example, the Java source is in a single file called PermissioningJavaBlade.java. Create this file in a suitable place within your development environment.

This example is a modified version of the OpenAuthenticator.java example supplied with Liberator. It uses Liberator’s Authentication Java API. Of course, if you wish, you can replace the example with a more sophisticated version of your own.

Here’s the example code:

package example.permissioning;

import java.util.Map;
import java.util.logging.Logger;

import com.caplin.server.auth.AuthenticationResult;
import com.caplin.server.auth.AuthenticationUser;
import com.caplin.server.auth.Authenticator;
import com.caplin.server.auth.DelayedResultReceiver;
import com.caplin.server.auth.MapObject;
import com.caplin.server.auth.PermissionUpdateType;
import com.caplin.server.auth.RTTPObject;
import com.caplin.server.auth.ServerNode;
import com.caplin.server.auth.SessionManager;
import com.caplin.server.auth.UserSession;
import com.caplin.server.logging.ServerLevel;

/**
 *
 * A simple Java Authenticator implementation that rejects attempts
 * to log in to the Liberator.
 * It also logs debug information to the Liberator's auth-rttp.log
 * logfile using the native logger.
 */
public class SimplePermissioning implements Authenticator
{
   private Logger logger;

   public void initialise( SessionManager sessionManager,
                           DelayedResultReceiver delayedResultReceiver,
                           ServerNode serverNode,
                           String loggerName )
   {
      this.logger = Logger.getLogger(loggerName);

      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: initialise called: delayedResultReceiver={0}, serverNode={1}, loggerName={2}",
                 new Object[] {delayedResultReceiver, serverNode, loggerName});
   }

   public AuthenticationResult checkUser( UserSession session )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: checkUser called: userSession={0}",
                 new Object[] {session});
      return AuthenticationResult.INVALID_USER; // All user login attempts are invalid.
   }

   public AuthenticationResult releaseUser( UserSession session )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: releaseUser called: userSession={0}",
                  new Object[] {session});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult newObject( RTTPObject object, RTTPObject parent )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: newObject called: object={0}, parent={1}",
                 new Object[] {object, parent});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult releaseObject( RTTPObject object )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning releaseObject called: object={0}",
                 new Object[] {object});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult checkRead( UserSession session, RTTPObject object )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: checkRead called: sessionId={0}, object={1}",
                 new Object[] {session.getSessionId(),
                 object});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult checkWrite( UserSession session, RTTPObject object,
                                           Map<String, String> fields )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: checkWrite called: sessionId={0}, object={1}, fieldMap={2}",
                 new Object[] {session.getSessionId(),
                 object,
                 fields});
      return AuthenticationResult.DENY;
   }

   public AuthenticationResult mapObject( UserSession session, MapObject mapObject )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: mapObject called: sessionId={0}, mapObject={1}",
                  new Object[] {session.getSessionId(),
                  mapObject});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult requestObject( UserSession session, RTTPObject object )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: requestObject: sessionId={0}, object={1}",
                 new Object[] {session.getSessionId(),
                 object});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult discardObject( UserSession session, RTTPObject object )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: discardObject: sessionId={0}, object={1}",
                 new Object[] {session.getSessionId(),
                 object});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult authoriseHTTP( AuthenticationUser user )
   {
   logger.log(ServerLevel.DEBUG_LEVEL,
              "SimplePermissioning: authoriseHTTP called: user={0}",
              new Object[] {user});
   return AuthenticationResult.OK;
   }

   public AuthenticationResult checkUpdate( UserSession session, RTTPObject object,
                                            String data )
  {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: checkUpdate called: sessionId={0}, object={1}, data={2}",
                 new Object[] {session.getSessionId(),
                 object,
                 data});
      return AuthenticationResult.OK;
   }

   public AuthenticationResult checkPermissionUpdate( UserSession session, RTTPObject object,
                                                      String key, Map<String,
                                                      String> fieldValues )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: checkPermissionUpdate called: sessionId={0}, object={1}, key={2}, fieldValueMap={3}",
                 new Object[] {session.getSessionId(),
                 object,
                 key,
                 fieldValues});
      return AuthenticationResult.OK;
   }

   public void globalPermissionUpdate( RTTPObject object, String key,
                                       Map<String, String> fieldValues,
                                       PermissionUpdateType type )
   {
      logger.log(ServerLevel.DEBUG_LEVEL,
                 "SimplePermissioning: globalPermissionUpdate called: object={0}, key={1}, fieldValueMap={2}",
                 new Object[] {object, key, fieldValues});
   }

   public void shutdown()
   {
      logger.log(ServerLevel.DEBUG_LEVEL, "SimplePermissioning: shutdown called");
      // do nothing
   }
}

How is this example different to the OpenAuthenticator.java example supplied with Liberator?

If you look at the implementation of checkUser(UserSession) towards the top of the example, you’ll see that this method always returns AuthenticationResult.INVALID_USER, rather than AuthenticationResult.OK. This isn’t very useful behaviour for a real authentication module, but the main aim of this example is to show how to create a Permissioning Service blade whose authentication module will load and run, rather than go into the details of how to code a fully functioned module. You’ll see below that the simple behaviour of the module makes it easy to check whether the module is running by looking at the log files.

If you want to check out the behaviour of the module as implemented by its other methods, just change the return value of checkUser(UserSession) to AuthenticationResult.OK so that it will let you log on to the Liberator.

When you’ve completed the code in the PermissioningJavaBlade.java file, compile it into a JAR file (PermissioningJavaBlade.jar).

  • Ensure that the JAR containing the Liberator’s Authentication Java API is in the compilation classpath. This JAR is called javaauth.jar and it’s located in the lib/java/ directory of the deployed Liberator in the Deployment Framework.

  • Put the JAR in the directory <Framework-root>/kits/PermissioningJavaBlade/PermissioningJavaBlade/Liberator/lib/java/

Start the new Liberator Permissioning Service blade

  1. If you have exclusive use of the Deployment Framework, restart the whole system on your development server machine:

    ./dfw start

    This stops the Liberator and Transformer and any Adapter blades, and restarts them. (The command works out from the configured hostname settings which components it needs to start on the machine where the command is running.)

  2. Alternatively, if you share the Transformer and any Adapter blades with other developers and you don’t want to shut them down just to get your new blade running, stop and start the Liberator on it’s own:

    ./dfw start Liberator

When the Liberator is running:

  1. Clear your browser’s cache and record of logins, so that Liberator will prompt for login information.

  2. Go to the Liberator’s status page. It will prompt for a username and password.

    Enter admin and admin

    The status page won’t display any status information, because the login has been rejected.

  3. Look at the Java log file (java.log) in <Framework-root>/servers/Liberator/var

    It should contain an entry that confirms the authentication Java class has been created:

    14:37:25.403 +0000: INFO: Successfully created class authenticator
    (example.permissioning.SimplePermissioning)
  4. Look at the Liberator’s auth module log file (auth-rttpd.log) in <Framework-root>/servers/Liberator/var

    It should contain an entry that confirms the log in attempt has been rejected:

    2014/01/21-14:40:47.274 +0000: INFO: Thread [Thread-2/18]: javaauth :
    checkUser: sessionId=0lp75vR2TDnHw8L1QI8XwV,
    userName=admin, password=admin: Authentication result: Failure: Invalid User