LTPA Tokens
contendsCeptor support authenticating users using LTPA Tokens, and can also issue new LTPA Tokens to use as cookies to backend servers, thus enabling easy SSO with IBM products.
LTPA is short for Lightweight Third-Party Authentication - see more information here:Â https://en.wikipedia.org/wiki/IBM_Lightweight_Third-Party_AuthenticationÂ
Ceptor supports the most secure variant, LTPA2 signed by RSA keys and encrypted using AES encryption.
Configuration of LTPA Authentication Plugin
No matter if you need to issue new LTPA Tokens to others, or authenticate using tokens obtained elsewhere, you need to configure the LTPA Authentication plugin.
Enable it by adding the string dk.itp.security.authentication.ltpa.LTPAAuthenticationPlugin
to the list of authentication plugin in the property server.authenticationplugins
the Ceptor Session Controller.
You will also need to configure it, it supports the following configuration properties:
Name | Value | Description |
---|---|---|
ltpa.tokens | List of token names, separated by comma or semicolon | List of token names to load - allows you to specify multiple different tokens which each use their own set of keys |
ltpa.token.default.name | String | Name of token that will be used as default, if nothing else is indicated in the call. Note that if only one token is configured, that token name will be used as default so in that case this does not need to be specified. |
For the following <tokenname> is replaced with the name of the token | ||
ltpa.token.<tokenname>.authenticate | true/false | Set to true if authentication is allowed with this token - if false, LTPA tokens can be created for this, but authentication using such a token is not allowed. |
ltpa.token.<tokenname>.filename | String containing filename, macros are allowed. | Specify a filename to load properties from - if not specified, If properties are not specified, and the file this points to does not exist, a new one will be generated with new keys. Note that this file must be kept the same across all clusters and kept in sync with all servers consuming the LTPA keys. |
ltpa.token.<tokenname>.properties | Contents of LTPA key file | If specified, contains the contents of the key file - this key is in the format generated by the various IBM products. Example: #Mon May 21 10:27:07 CEST 2018 com.ibm.websphere.CreationDate=Mon May 21 10\:27\:07 CEST 2018 com.ibm.websphere.ltpa.version=1.0 com.ibm.websphere.ltpa.3DESKey=p7JQDC5aq5UIlfv5xtYsprRf8d8qItDvqthGSgXWQ14\= com.ibm.websphere.CreationHost=localhost com.ibm.websphere.ltpa.PrivateKey=hN2G2F59pWtFOVjUY...snipped...e81OlsaVp8\= com.ibm.websphere.ltpa.Realm=defaultRealm com.ibm.websphere.ltpa.PublicKey=AMKrclsDHhK...snipped...9vAQAB You can use this property to keep the keys in Ceptor's configuration instead of having them on disk on all servers within a cluster. Note that the keys are encrypted with the password. |
ltpa.token.<tokenname>.password | Password - may be encrypted. | Specify the password that the keys are encrypted with - see Encrypting or Obfuscating Passwords for details on keeping the password safe. |
ltpa.token.<tokenname>.create.userid | Mapper - used to specify userid in created tokens. Default: user:BasicRegistry/%{userid} | This mapper is used to specify the userid in a created token. The macro %{userid} will be replaced with the authenticated users userid, and %{xxxxx} will be replaced by any other input specified when calling the newToken() method on the authentication plugin. This can also be a script (javascript / groovy / python) which generated and returns the value to use. |
ltpa.token.<tokenname>.expiration.minutes | Long | Token expiration time in minutes - newly created tokens will expires after the configured number of minutes. Tokens created by the |
ltpa.token.<tokenname>.create.script | Script | This script is called when creating new tokens - it allows adding additional attributes to the token, such as the users groups, name or anything else you want to add to the token itself. |
ltpa.token.<tokenname>.parse.script | Script | Called when parsing the token - it allows you to specify which attributes are mapped to what within the session. |
Example:
<group name="ltpa" description="LTPA Tokens"> <property name="ltpa.token.liberty1.authenticate" value="true" description="If true, allow authentication using tokens signed by these keys"/> <property name="ltpa.token.liberty1.create.script" value="%{script}" description="Script called when creating token - allows adding additional attributes to the generated token"/> <property name="ltpa.token.liberty1.create.userid" value="user:BasicRegistry/%{userid}" description="Macro/script for specifying userid inside LTPA token"/> <property name="ltpa.token.liberty1.expiration.minutes" value="30" description="Expiration time in minutes, when creating new tokens"/> <property name="ltpa.token.liberty1.filename" value="${portalprotect.home}/config/ltpa.keys" description="Name of file that keys are stored within - created if it does not exist upon startup"/> <property name="ltpa.token.liberty1.parse.script" value="%{script}context.session.userid = context.token.getAttributes('u')[0];" description="Script used when parsing token - used to parse token content into session"/> <property name="ltpa.token.liberty1.password" value="changeit" description="Password that keys are encrypted with"/> <property name="ltpa.token.liberty1.properties" value="" description="If set, used instead of filename - can contain the LTPA keys file contents"/> <property name="ltpa.tokens" value="liberty1" description="List of LTPA tokens"/> </group>
Scripts
The scripts are executed with a a variable; context pointing to an instance of this class:
package dk.itp.security.authentication.ltpa; import dk.itp.security.authentication.ltpa.token.Token; import dk.itp.security.passticket.User; import portalprotect.org.json.JSONObject; public class LTPAState { /** Contains input from the caller - e.g. the gateway */ public JSONObject jo; /** The session being updated or used to create the token */ public User session; /** LTPA Token configuration - contains the values from the configuration */ public LTPATokenConfig cfg; /** The token used as input when authenticating or newly created when creating a token */ public Token token; }
The JSON Object "jo" contains the input from the caller - e.g. the gateway. This allows specifying additional values when creating the token, and these can be used by the script. Note that he token variable is not available when calling the create.userid
script - it is only present after creation and available for the create.script
and parse.script
to use.
See Authentication Plugins for more information.
Example script for parsing:
// Copy the userid directly from the token to the user // Most LTPA tokens only contain this and no other attributes. context.session.userid = context.token.getAttributes('u')[0];
Example script for creating and adding additional attributes to a token:
// Add the username context.token.addAttribute("name", context.session.username); // Add each group - will end up as an array of string in the token. if (context.session.userGroups != null) { for(int i = 0; i < context.session.userGroups.length; i++) { context.token.addAttribute("group", context.session.userGroups[i]); } }
Creating New Tokens Programmatically
To create a new token, call:
JSONObject json = new JSONObject(); json.put("tokenname", "liberty1"); json.put("additionalattribute", "available to the create script"); String result = Agent.getInstance().newToken(sessionId, json.toString()); // result is now a JSON string with two attributes; token and expiration JSONObject resultObject = new JSONObject(result); String generatedToken = resultObject.get("token"); long expiresAt = resultObject.get("expiration"); // Time this expires at, in milliseconds since 1/1 1970, GMT.
Programmatically Authenticating Using a Token
Normally, you would use the Ceptor Gateway and configure the LTPA Authentication plugin (see Location - Authentication ) but to do it programmatically, you can call this:
// Use JSON input - allows you to specify additional attributes that are available to the scripts JSONObject json = new JSONObject(); json.put("tokenname", "liberty1"); json.put("token", myLTPAToken); json.put("myadditionalattribute", "myvalue"); Agent.getInstance().login(sessionId, AuthTypes.AUTHTYPE_LTPA, "ltpa", json.toString()); // Alternatively - Use the token directly, no JSON Agent.getInstance().login(sessionId, AuthTypes.AUTHTYPE_LTPA, "liberty1", myLTPAToken);
© Ceptor ApS. All Rights Reserved.