# Create a Java-based Liberator auth module

You can write your own Liberator auth module in Java using Liberator’s [Java Auth API](https://docs.caplin.com/developer/api/auth_java_sdk/latest/).

<dl><dt><strong>📌 NOTE</strong></dt><dd>

If you want to integrate Liberator with your existing permissioning system, consider using Caplin’s Permissioning Auth Module (PAM). The PAM subscribes to live permissioning data provided by one or more permissioning integration adapters, which you write using the Permissioning Integration API.

The PAM is packaged in the Permissioning Service blade, available as a separate download from Liberator. For more information about the Permissioning Service, see [Permissioning](../platform-architecture/permissioning.md).
</dd></dl>

## 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 included in the Deployment Framework.

You’ll need a [Liberator](../liberator/index.md) 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](cdf-deploy-platform-components-to-the-framework.md). 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.

**📌 NOTE**\
Make sure that your Liberator licence allows access to Liberator’s javaauth authentication module. The trial licence supplied with Liberator doesn’t allow you to use javaauth. To see whether or not javaauth is licenced, [deactivate](cdf-activate-and-deactivate-blades.md) the Liberator’s built-in OpenPermissioning blade, [activate](cdf-activate-and-deactivate-blades.md) its JavaOpenPermissioning blade, and then start the Liberator. If javaauth isn’t licenced, Liberator reports "rttpd: Cannot load module javaauth - error not licenced"**_._**

<dl><dt><strong>💡 TIP</strong></dt><dd>

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](cdf-the-deployment-framework-command-utility-dfw.md).
</dd></dl>

### Blade structure

Assuming the blade is located in the Deployment Framework at _&lt;Framework-root>/kits/&lt;blade_name>/&lt;blade_name>/_, relative to this path:

* the blade compatibility information is in the file `control`
* the blade’s [field definitions](../datasource/datasource-field-definitions.md) are in the file `blade_config/fields.conf`
* Liberator related configuration for the blade is in the file `Liberator/etc/rttpd.conf`
* The Liberator Java auth module’s JAR file, compiled from the Java source file, is in _Liberator/lib/java_

## Summary

In brief, you create the blade using the following steps, which are given in more detail further down the page:

1. [Create the blade’s directory structure](#create-the-blades-directory-structure).
2. [Update Liberator’s configuration](#update-liberators-configuration).
3. [Update the blade control file](#update-the-blade-control-file).
4. [Deploy the blade to your development environment](#deploy-the-blade-to-your-development-environment)
5. [Write the Java auth module](#write-the-java-auth-module).
6. [Start the new Liberator permissioning blade](#start-the-new-liberator-permissioning-blade).
7. [Package the new blade](#package-the-new-blade).

## 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 __&lt;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

1. [Edit java.conf](#edit-javaconf)
2. [Edit javaauth.conf](#edit-javaauthconf)
3. [Create the configuration override file](#create-the-configuration-override-file)
4. [Edit rttpd.conf](#edit-rttpdconf)

### Edit java.conf

Using a suitable text editor, make the following changes to the file _Temp_Java_blade/PermissioningJavaBlade/Liberator/etc/java.conf_

1. Change the file heading to 'Liberator Java configuration for PermissioningJavaBlade'
2. Change the value of the `add-javaclass > class-name` configuration option to `example.permissioning.SimplePermissioning`
3. Change the value of the `add-javaclass > classpath` configuration option to "${ccd}/../lib/java/SimplePermissioning.jar"

The configuration sample below shows the `java.conf` file with the changes highlighted:

```
#
# Liberator Java configuration for PermissioningJavaBlade 
# module 
#
#

#
# 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
#
# Refer to the Deployment Framework documentation in the doc
# folder for more details.
#

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   example.permissioning.SimplePermissioning
    class-id     authenticator
    classpath    "${ccd}/../lib/java/SimplePermissioning.jar"
end-javaclass
```

### Edit javaauth.conf

Using a suitable text editor, make the following changes to the file _Temp_Java_blade/PermissioningJavaBlade/Liberator/etc/javaauth.conf_

1. Change the file heading to "Liberator Java auth configuration for PermissioningJavaBlade."
2. Change the value of the include-file configuration item to "

   $\{BASE}/global_config/overrides/PermissioningJavaBlade/Liberator/etc/javaauth.conf"

The configuration sample below shows the `javauth.conf` file with the changes highlighted:

```
#
# Liberator Java auth configuration for PermissioningJavaBlade.
#
#

#
# DO NOT EDIT THIS FILE !!!
#
#
# If you need to change any Java authorisation configuration, do so by updating
#
#    global_config/environment.conf
#    global_config/overrides/servers/Liberator/etc/javaauth.conf
#
#
# Refer to the Deployment Framework documentation in the doc
# folder for more details.
#

###########################################################
#
#  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/PermissioningJavaBlade/Liberator/etc/javaauth.conf"
```

### Create the configuration override file

Liberator won’t start if the override file specified in the `include-file` configuration item does not exist.

Create a file called `<Framework-root>/global_config/overrides/PermissioningJavaBlade/Liberator/etc/javaauth.conf` with the content below:

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

### Edit rttpd.conf

Using a suitable text editor, make the following changes to the file `Temp_Java_blade/PermissioningJavaBlade/Liberator/etc/rttpd.conf`

1. Change the file heading to "Liberator configuration for PermissiongJavaBlade"

The configuration sample below shows the `rttpd.conf` file with the changes highlighted:

```
#
# Liberator congfiguration for PermissioningJavaBlade.
#
#

#
# DO NOT EDIT THIS FILE !!!
#
#
# If you need to change any configuration, do so by updating
#
#    global_config/environment.conf
#    global_config/overrides/servers/Liberator/etc/rttpd.conf
#
# Refer to the Deployment Framework documentation in the doc
# folder for more details.
#

include-dir "${ccd}"

auth-module    javaauth
```

## Update the blade control file

Only one permissioning blade can be active at a time. Each Liberator service blade contains a [blade control file](cdf-the-blade-control-file.md), which lists the blades with which the blade is incompatible.

Using a text editor, make the following changes to the file `Temp_Java_blade/PermissioningJavaBlade/control`

1. Add "JavaOpenPermissioning" to the list of conflicting blades

The configuration sample below shows the file `Temp_Java_blade/PermissioningJavaBlade/control` with the changes highlighted:

```
Conflicts: OpenPermissioning JavaOpenPermissioning PermissioningService TokenPermissioning
```

## Deploy the blade to your development environment

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

1. ZIP the blade’s directory hierarchy into a skeleton blade kit. The .zip archive must have a name of the form `<blade_name>-<version_number>.zip`. In the `Temp_Java_blade` directory, execute the following command from the command line:

   ```
   zip --recurse-paths PermissioningJavaBlade-000001.zip PermissioningJavaBlade
   ```
2. Navigate to &lt;Framework-root> and deactivate the existing built-in permissioning blades:

   ```
   ./dfw deactivate OpenPermissioning JavaOpenPermissioning
   ```

   **💡 TIP**\
   You can first check the activation status of these blades by running `./dfw versions`
3. Navigate to _&lt;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](cdf-active-and-inactive-blades.md) state.

## Write the Java auth module

This is the functional part of the blade that defines the actions you need it to perform. It is written using Liberator’s [Authentication Java API](https://docs.caplin.com/developer/api/auth_java_sdk/latest/). 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. 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.

The code example below is a modified version of the `OpenAuthenticator.java` example supplied with Liberator. Of course, if you wish, you can replace the example with a more sophisticated version of your own.

**❗ IMPORTANT**\
Version 7 of Liberator’s Authentication Java API added an extra parameter to the method signatures for `Authenticator.checkRead` and `Authenticator.checkWrite`. This is a breaking change. Check the API documentation for your version of the Liberator Authentication Java API for the correct method signature to use.

Here’s the example code (for a Liberator 7 auth module):

```java
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, String requestedName )
   {
      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, String requestedName,
                                           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
   }
}
```

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

### Package the Java class

When you’ve completed the code in the _PermissioningJavaBlade.java_ file, package it as a JAR archive (`PermissioningJavaBlade.jar`), and put the archive in the directory `<Framework-root>/kits/PermissioningJavaBlade/Liberator/lib/java/`

## Start the new Liberator permissioning blade

1. Run the following command from the root of the Deployment Framework to restart Liberator:

   ```
   ./dfw start Liberator
   ```
2. Clear your web browser’s cache and record of logins, or close all browser windows and open a new browser window.
3. Open the Liberator’s status page and attempt to login with username 'admin' and the password 'admin'. Your credentials will be rejected.
4. Look at the Java log file (`java.log`) in _&lt;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)
   ```
5. Look at the Liberator’s auth module log file (`auth-rttpd.log`) in _&lt;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
   ```

## Package the new blade

When you’ve developed and tested the new blade to your satisfaction, you’ll need to package it up so it can be deployed on your production system. See How can I... [Package a custom blade](cdf-package-a-custom-blade.md).

---

**See also:**

* [Add a custom subject mapper to a Permissioning Service blade](cdf-add-a-custom-subject-mapper-to-a-permissioning-service-blade.md)
* [Package a custom blade](cdf-package-a-custom-blade.md)
* [Set up server failover capability](cdf-set-up-server-failover-capability.md)
* [Deploy Platform components to the Framework](cdf-deploy-platform-components-to-the-framework.md)
* [Create a Lua-based Transformer Service blade](cdf-create-a-lua-based-transformer-service-blade.md)
* [Create a Java-based Transformer Service blade](cdf-create-a-java-based-transformer-service-blade.md)
* [Start and stop components and blades](cdf-start-and-stop-components-and-blades.md)
* [Liberator’s Authentication Java API](https://docs.caplin.com/developer/api/auth_java_sdk/latest/)
