This section does not cover securing an instance of a TDI Server; this is discussed in TDI Server Instance Security. Instead, this section discusses how client applications can contact a server.
IBM TDI supports the concept of a Remote *** (also known as just "Server API"), where client tasks can invoke tasks on a remote TDI Server by means of an access layer called ***.
The "remote Server" could very well be running on the same computer as the client application, for example if we start up a Server instance on your local computer and then access it using the Remote API through the loopback address, 127.0.01. All concepts discussed below are still valid, even though the remote Server runs locally.
The Server API calls address the following areas:
Increasing needs for remote server access for each running TDI server have resulted in a change from local access by default to remote access by default. As of 7.1, the remote server API is enabled by default. Prior to 7.1, the server API was enabled only for local access by default, where local access means access from the same Java Runtime Environment (JRE). To ensure security, remote access requires SSL client authentication. SSL access using client authentication is provided with the sample keystore and truststore deployed with TDI.
The Server API itself is documented in the TDI Java API documentation (TDI_install_dir/docs/api; we can launch a browser to display this documentation by selecting Help -> Welcome -> JavaDocs in the CE). The package of interest in this context is com.ibm.di.api. Also see the chapter called "Using the Server API" in IBM TDI V7.1 Reference Guide.
The Configuration Editor uses the Remote API to talk to the server we use to test-run the solutions. If this TDI server is running on the same machine, it is often called the "local development server". For setups where the deployment platform does not support the Configuration Editor (for example, z/OS or i5/OS), we can run the development server on the deployment server, and the Configuration Editor on a supported platform like Windows (this way of running we call the "Remote Configuration Editor"). This design provides a uniform interface for both remote and local Config files. For some aspects of the Configuration Editor talking to a remote deployement server, see Using the Remote Configuration Editor.
The Server API is configured through a set of server properties (see Configuring the Server API). These properties are specified in the global.properties configuration file of the TDI Server. Some of the properties, in turn, point to additional configuration files and keystore files.
The Server API provides a number of security-related features (which both TDI Solution-based clients as well other client applications have to deal with). There are three aspects to Server API Access Security:
The relevant properties are:
Property | Default value | Description |
---|---|---|
api.on | true | If set to true, the Server API is initialized on startup and can be used; otherwise the Server API is not initialized and cannot be used. All other properties whose names start with "api." are only taken into account if api.on is set to true. |
api.audit.on | false | If set to true, the audit feature is turned on. If it is set to true, an audit entry is created at each audit point, even if the audit notifications are suppressed. |
api.user.registry | serverapi/registry.txt | If configured, specifies the Server User Registry file name. |
api.user.registry.encryption.on | false | If set to true, the Server API decrypts the Server User Registry file on startup. |
api.remote.on | true | If set to true, the remote RMI part of the Server API is initialized and can be used; otherwise, the remote RMI part of the Server API is not initialized and cannot be used. |
api.remote.ssl.on | true | If set to true, SSL with client and server authentication is used on RMI connections of the Server API and its JMX layer; and the Server API uses the Server certificate and private key (the one specified through the api.keystore and api.key.alias properties) for SSL connections. RMI clients must trust that certificate. If set to false, no SSL is used for client connections and no authentication and authorization is performed; connections are accepted from the local host and from hosts listed in the api.remote.nonssl.hosts property; if api.remote.nonssl.hosts is empty, only connections from the local host are accepted. |
api.remote.ssl.client.auth.on | true | If set to true, the SSL client authentication for remote Server API is switched on. |
api.remote.naming.port | 1099 | If specified, the port on which the RMI registry listens for requests. |
api.remote.server.ports | 8700-8900 | The range of ports that may be used by the various
RMI services. Entered as a comma separated list allowing hyphen-marked
intervals (for example 1, 3-5, 10). Port numbers must be > 0 and <=
65536.
The server will use these ports to listen for incoming RMI service requests, in addition to listening on the ports defined by other properties. For outgoing RMI service requests, random port numbers may be used. |
com.ibm.di.default.bind.address | * | The default bind address for the whole TDI Server - the components and the Server API. * means bind to all available network interfaces. Missing or invalid value binds to all interfaces, too. Only one IP address should be provided as value. This property will affect all Server Connectors that create a Server Socket. |
api.remote.bind.address | * | The bind address for the RMI Server API. Overrides the com.ibm.di.default.bind.address property. * means connect to all available network interfaces. Missing or empty value means fall back to com.ibm.di.default.bind.address. Only one IP address should be provided as value. |
api.truststore | testserver.jks | If specified, the keystore file that contains the public certificates of all remote users of the Server API. |
{protect}-api.truststore.pass | server (encrypted by default) | If specified, the password for the keystore file named through the api.remote.server.truststore property. |
api.remote.nonssl.hosts | If specified, shows a list of IP addresses to accept non-SSL connections from (host names are not accepted). Use space, comma or semicolon as a delimiter between IP addresses. This property is only taken into account when api.remote.ssl.on is set to false. | |
api.jmx.on | false | If set to true, the JMX layer of the Server API is initialized on startup and can be used; otherwise, the JMX layer is not initialized and cannot be used. |
api.jmx.remote.on | false | If set to true, the remote JMX interface (as defined by JSR160) is initialized and can be used; otherwise the remote JMX interface is not initialized and cannot be used. |
api.config.folder | configs | If set to TDI_root/configs, only the configuration files placed in this folder can be edited through the Server API. |
api.config.lock.timeout | 0 | If set to 0, there is no timeout. |
api.custom.method.invoke.on | false | The ability to use Session.invokeCustom() methods can be turned on or off (the default is false, or off). If the value of this property is set to true then users can use these methods, otherwise an Exception will be thrown. |
api.custom.method.invoke.allowed.classes | If specified, gives the list of classes that can be invoked directly by the Server API methods for custom method invocation (Session.invokeCustom(...)). This property is only taken into account if api.custom.method.invoke.on is set to true. The classes in this list must be separated by a space, a comma or a semicolon. | |
api.custom.authentication. | [ldap] | If specified, points to a JavaScript text file that contains custom authentication code. To enable the built-in LDAP/JAAS Authentication mechanism, set this property to [ldap]/[jaas]. |
com.ibm.di.server.id | If specified, contains the server ID. Assign a unique value for each server from the set of servers that are running on the same IP and Port. | |
api.config.load.timeout | 2 | If specified, contains the serverapi config load timeout value in minutes. Added in TDI v7.0. |
api.notification.suppress |
di.server.api.authenticate |
If specified, gives a list of server notification types that we want to suppress. Notifications of suppressed types are not propagated by the notifications framework. Notification types in the list are separated by spaces. We can include wildcards. Example: api.notification.suppress=di.al.* di.ci.startThe above example suppresses all AssemblyLine related notifications as well as notifications for starting a configuration instance. If the property is missing or is empty, no notifications are suppressed. Added in TDI v7.0. |
api.client.ssl.custom.properties.on | true | Enables custom SSL properties for Server API clients. If true, the api.client.* properties will be used by Server API clients. Otherwise the default javax.net.ssl.* properties will be used. Added in TDI v7.1. |
api.client.keystore | serverapi/testadmin.jks | Keystore for Server API clients. |
api.client.keystore.pass | administrator | Password for the keystore specified by the "api.client.keystore" property. |
api.client.keystore.type | jks | Type of the keystore file specified by api.client.keystore; optional property, if not specified the default keystore format for the JVM will be used |
api.client.key.pass | administrator | Password for the private key. The key is located in the keystore specified by the "api.client.keystore" property. |
api.client.truststore | serverapi/testadmin.jks | Truststore for Server API clients. |
api.client.truststore.pass | administrator | Password for the truststore specified by the "api.client.truststore" property. |
api.client.truststore.type | jks | Type of the keystore file specified by api.client.truststore; optional property, if not specified the default keystore format for the JVM will be used |
The Java system properties that the Server API uses for its configuration are the same, regardless of whether the client is a Java program or a different instance of the TDI Server. What should be noted though is that the way these Java system properties are set might be different. In TDI these properties are normally set by editing the global.properties or solution.properties files, whereas in a Java program they can be specified either at the command line using the -D Java command line switch or by using Java code within the Java program using the java.lang.System.setProperty(key,value) standard Java method.
When the Remote Server API is accessed from a client on a Virtual Private Network (VPN), the VPN assigns an IP address to the Server API client computer. This VPN-assigned IP address needs to be specified in an RMI Java system property. If the Server API client is the Remote Configuration Editor, then this property can be set in global.properties or solution.properties by adding the following line to the properties files:
java.rmi.server.hostname=<IP_address>
Where IP_address is the VPN-assigned IP address.
If the Server API client is a custom Java program, then this property can be set from within the Java code in the following way:
java.lang.System.setProperty("java.rmi.server.hostname", "IP_Address");
where IP_address is the VPN-assigned IP address.
Note that the RMI Java system property needs to be set before any Server API related RMI code.
The Server API can be used in a variety of ways:
and so on.
The Server API provides two sets of interfaces - local and remote. It is only the remote interfaces that can use SSL. The local interfaces do not use SSL as the access is within the boundaries of the Java Virtual Machine. TDI can act as a server, as a client; as well as both as a client and as a server in a Server API access scenario. When SSL is used with the Server API, then a keystore and a truststore must be configured. There are two options for configuring these. Which of them is used depends on whether the Java System property api.client.ssl.custom.properties.on exists and on its value.
When the Java System property api.client.ssl.custom.properties.on is set to true, then SSL is configured through the following TDI Server API-specific Java System properties:
Use the Server API specific SSL properties when your client application is using the standard Java SSL properties. The standard Java SSL properties are properties used to configure another SSL channel used by the same application.
We can specify these properties as JVM arguments on the command line, for example:
java MyTDIServerAPIClientApp -Dapi.client.ssl.custom.properties.on=true -Dapi.client.truststore=C:\TDI\serverapi\testadmin.jks -Dapi.client.truststore.pass=administrator -Dapi.client.keystore=C:\TDI\serverapi\testadmin.jks -Dapi.client.keystore.pass=administrator
This example refers to the sample "testadmin.jks" keystore file shipped with TDI. Note that it contains both the client private key and also the public key of the TDI Server, so we use it both as a keystore and truststore.
We can specify these properties in global.properties or solution.properties when the client is a TDI server.
When the Java System property api.client.ssl.custom.properties.on is missing or when it is set to "false", then the standard JSSE system properties are used for configuring the SSL channel. Follow the standard JSSE procedure for configuring the keystore and truststore used by the client application.
We can specify these properties as JVM arguments on the command line, for example:
java MyTDIServerAPIClientApp -Djavax.net.ssl.keyStore=C:\TDI\serverapi\testadmin.jks -Djavax.net.ssl.keyStorePassword=administrator -Djavax.net.ssl.trustStore=C:\TDI\serverapi\testadmin.jks -Djavax.net.ssl.trustStorePassword=administrator
Also these properties can be specified in global.properties or solution.properties when the client is a TDI server.
Server API authentication is usually referred to in the context of a remote Server API client establishing a Server API session. This scenario represents the substance of the Server API authentication logic as the Server API provides several different kinds of client authentication. But before diving into the different authentication mechanisms let us discuss the scenario in which a local client establishes a local Server API session.
A local client session is a session established by a client which runs in the same Java Virtual Machine as the TDI server. Examples of such sessions are local sessions for access to the local Server API established from JavaScript code in hooks or in a Script component, from Connectors and Function Components which are executed as part of an AssemblyLine which runs in the same TDI server, and so on. When a local client establishes a local Server API session, the client has two options:
A remote client session is a session established by a client which does not run in the same Java Virtual Machine as the TDI server. Examples of such sessions are sessions for access to a remote Server API established from the Configuration Editor, or a Javaâ„¢ application wishing to access a TDI Server. For access of this kind there are the following methods of authentication to the TDI Server:
The Java Authentication and Authorization Service (JAAS) is supported as an authentication module for TDI Server APIs. JAAS is a set of APIs that enables services to authenticate and enforce access controls upon users. The JAAS authentication is facilitated by the TDI Server API. No changes are required on the TDI Server API clients such as CLI and AMC in order to use the JAAS authentication module.
In order to use JAAS authentication, configure the appropriate properties in global.properties or solution.properties and the JAAS Logon should be installed.
This is the only authentication mechanism available in TDI 6.0. SSL-based authentication is based on a two-stage verification of the client's credentials.
Attention: A client certificate example, corresponding to the Server certificate example in file testserver.jks is provided in file serverapi/testadmin.jks; the certificate's password is "administrator". As with all default security parameters we should not rely upon these and generate your own client/server certificates and specify these in the properties files. See Certificates for the TDI Web service Suite.
The truststore is kept in the file indicated by the api.truststore property.
The SSL-based authentication mechanism can be switched off in TDI 7.1. An additional property is available in the TDI Server configuration file global.properties or solution.properties: api.remote.ssl.client.auth.on. When this property is set to "true", the TDI Server requires client authentication within the SSL handshake (the TDI 6.0 mechanism for SSL-based authentication). SSL client authentication for TDI Server API does not depend on whether a username and password pair is supplied. This means that if no username and password pair is supplied, the TDI 6.0 mechanism for SSL-based authentication is used. And if a username and password pair is supplied then the client still needs to send its SSL certificate for authentication, but the User ID for authentication (and at a later step authorization) is taken from the username supplied.
When api.remote.ssl.client.auth.on is set to "false", SSL-based authentication cannot be used. When the property is not specified a value of "false" is assumed.
This mechanism requires a client to supply a username and password on the opening of his Server API connection to the TDI server. In order to configure this authentication method an authentication hook is used.
This hook allows the provision of custom JavaScript code that performs username and password based authentication. This hook allows bundlers/deployers to write customized JavaScript code, which given a username and password pair determines whether the authentication should succeed or not.
The property allowing for this custom JavaScript authentication is specified in the TDI Server configuration file global.properties or solution.properties: api.custom.authentication. The api.custom.authentication property points to a JavaScript text file on the disk that contains custom authentication code. If this property is not specified then the TDI 6.0 SSL-based authentication mechanism is used. When the api.custom.authentication property is specified, the JavaScript code contained in the specified file is executed for each username and password based authentication request.
The authentication script has access to the predefined script object userdata. This object provides the following two public members:
The script is free to perform whatever checks and authentication actions it needs. It returns whether the authentication is successful through the ret object:
The description and error code fields is provided by the AuthenticationException thrown by the ServerAPI on unsuccessful authentication.
The authentication script has access to the main script object. It can be used for logging custom messages in the TDI Server log file (for example main.logmsg("Authentication failed for user : " + userdata.username)).
An example authentication hook JavaScript file is available (in TDI_install_dir/examples) in order to demonstrate what the JavaScript of an authentication hook could look like. This example JavaScript can also be used as the basis of real-world TDI authentication hooks. The example JavaScript demonstrates how an authentication hook can use an LDAP server (Tivoli Directory Server, Active Directory, and so on) for authenticating client requests.
The JavaScript file is named "ldap_auth.js" and is installed in the examples/auth_ldap TDI Server folder. To deploy this sample LDAP authentication mechanism users can copy that file to the TDI solution folder and specify api.custom.authentication=ldap_auth.js in global.properties or solution.properties. The JavaScript code in "ldap_auth.js" tries to bind to an LDAP Server with the specified username and password. If the bind operation is successful, the script indicates a successful authentication, otherwise the authentication is rejected. The details for connecting to the LDAP Server like the server URL are specified in the "ldap_auth.js" script - this means that users have to edit this file and set the proper connection parameters before using the script. Here is the sample "ldap_auth.js" script:
env = new Packages.java.util.Hashtable(); env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory"); env.put("java.naming.provider.url", "ldap://192.168.113.54:389"); env.put("java.naming.security.principal", userdata.username); env.put("java.naming.security.credentials", userdata.password); env.put(Packages.javax.naming.Context.SECURITY_AUTHENTICATION, "simple"); main.logmsg("Authentication request for user: " + userdata.username); try { mCtx = new Packages.javax.naming.directory.InitialDirContext(env); ret.auth = true; } catch(e) { ret.auth = false; ret.errordescr = e.toString(); // ret.errorcode = "49"; }
The TDI Server API provides support for LDAP Authentication. This allows us to leverage your existing LDAP infrastructures that already hold User IDs and Passwords.
In order to use LDAP authentication the appropriate properties must be configured in global.properties or solution.properties. The list of these properties along with their descriptions follows:
If this parameter is missing or is set to "false" the Server API logs the LDAP Authentication initialization error but the Server API is started. An attempt to initialize the LDAP Authentication module is made on each authentication request received by the Server API until the LDAP Authentication module is initialized.
If a required property is missing an exception is thrown on initialization.
If the value of either api.custom.authentication.ldap.searchbase or api.custom.authentication.ldap.userattribute is missing no search context is initialized and no searches is performed during the actual user authentication. (No search means that the bind to the LDAP Server is attempted directly with the username and password provided for authentication.)
When api.custom.authentication.ldap.admindn is provided a search context is created using "simple" authentication. If an error occurs during the search context initialization, the initialization of the LDAP Authentication module fails and an exception is thrown.
When api.custom.authentication.ldap.admindn is not provided a JNDI search context is created using JNDI "anonymous" bind.
If the search context cannot be initialized using api.custom.authentication.ldap.admindn, authentication fails directly - no anonymous bind is attempted.
On each attempt to authenticate a user the LDAP Authentication module is passed the username and the password for the user to be authenticated. The following authentication paths are possible:
In this case no searches are performed and a bind to the LDAP Server is attempted directly with the username and password provided for authentication. If the bind succeeds the authentication is considered successful, otherwise it is considered that the authentication failed.
To ease administration, TDI allows permissions to be configured for groups the same way as they are configured for users. We can set permissions in the User Registry using exactly the same syntax as you would for a user. The fact is that the User Registry does not care whether a security entity is a group or a user. The distinction between users and groups is drawn during the authentication process.
Group membership is configured in the LDAP directory, against which TDI authenticates users. If a user is a member of some LDAP group, all permissions for that group are automatically inherited by the user when the user is authenticated. Group support is disabled by default, so turn it on.
The system properties that are related to LDAP group support are:
Active Directory example
This example shows how to configure group support to work with an Active Directory server:
api.custom.authentication.ldap.groupsupport=true api.custom.authentication.ldap.usermembershipattribute=tokenGroups api.custom.authentication.ldap.usermembershipattributecontent=objectSID api.custom.authentication.ldap.groupnameattribute=sAMAccountName api.custom.authentication.ldap.groupsearchbase=DC=mytestadserver,DC=com api.custom.authentication.ldap.binaryattributes=objectSID tokenGroups
The 'tokenGroups' attribute is a calculated attribute that exists for all users in Active Directory.
It contains a collection of the Security Identifiers (SIDs) for all security groups that the user is a member of.
This collection contains only security groups (distribution groups, used for e-mail, are not included) and it contains all security groups including nested and primary groups.
The Security Identifiers are binary attributes so they must be set in the api.custom.authentication.ldap.binaryattributes property.
In the above example, groups are named by their "sAMAccountName" LDAP attribute in the TDI User Registry.
Tivoli Directory Server example
This example shows how to configure group support to work with Tivoli Directory Server:
api.custom.authentication.ldap.groupsupport=true api.custom.authentication.ldap.usermembershipattribute=ibm-allGroups api.custom.authentication.ldap.usermembershipattributecontent=dn api.custom.authentication.ldap.groupnameattribute=dn api.custom.authentication.ldap.groupsearchbase=ou=mytestou,c=mytestcountry
For a given user entry, the "ibm-allGroups" operational attribute enumerates all static, dynamic and nested groups, to which that user has membership.
Notes:
Host based authentication is used, when SSL is turned off by specifying api.remote.ssl.on=false in global.properties or solution.properties files. Host based authentication is configured using the api.remote.nonssl.hosts property. This property specifies the list of host IP addresses from which remote Server API clients can use the Server API without specifying a username and password.
The syntax of this list of hosts is: a list of IP addresses (host names are not accepted); use a space, a comma or a semicolon as a delimiter between IP addresses. An example value of this property would be:
api.remote.nonssl.hosts=192.168.111.222, 192.168.112.158
When a client using host based authentication is successfully authenticated, then the client is granted admin authorization authority. That is why adding IP addresses to this list must be done with great care. It is not advisable to use host based authentication in production environment because of its security issues. Host based authentication would normally be used while developing a solution or when doing a demo.
The following authentication options are available:
When SSL is used and the remote client application uses Server API listener objects, then the client application must have its own certificate that is trusted by the TDI Server (this is analogous to the setup for SSL client authentication). If there is no client certificate trusted by the TDI Server, the listener objects do not work and the remote client application cannot receive notifications from the TDI Server.
The remote JMX layer of the Server API does not support username and password based authentication. It ignores the api.custom.authentication properties. Regardless of the value of these properties and whether custom authentication is enabled or not for the Server API, the remote JMX layer performs the following authentication:
The net result is that the Server API JMX layer does not support username and password authentication:
Authentication configuration examples:
api.remote.ssl.on=false api.remote.nonssl.hosts=192.168.113.51, 192.168.113.52 api.custom.authentication=ldap_auth.jsSSL is not used.
api.remote.ssl.on=true api.remote.ssl.client.auth.on=false api.custom.authentication=ldap_auth.jsSSL is used for remote Server API communication.
api.remote.ssl.on=true api.remote.ssl.client.auth.on=true api.custom.authentication=ldap_auth.jsSSL is used for remote Server API communication and the Server requires SSL client authentication.
api.remote.ssl.on=true api.remote.ssl.client.auth.on=true api.custom.authentication=(as an alternative, the "api.custom.authentication" property may be missing entirely)
SSL is used for remote Server API communication and the Server requires SSL client authentication.
After a client Server API session request is authenticated it needs to be authorized.
Users of the Remote API can be assigned several roles; a role defines a list of Server API calls that can be executed by the user and also defines in what context these calls can be executed. A Server API method can be executed if there is at least one role assigned to the user that allows the execution of this method in the context the user tries to execute it. For example, a role can grant the user rights to execute only specific AssemblyLines from a specific configuration. Refer to Server API User Registry for details on how to create the file that holds these user rights.
Authorization is based on the user id. Depending on the authentication mechanism used the user id is retrieved in a different way:
Users of the Remote API are assigned roles; a role defines a list of Server API calls that can be executed by the user and also defines in what context these calls can be invoked. For example, a role can grant the user rights to invoke only specific AssemblyLines from a specific configuration.
Several roles can be assigned to a user, including assigning the same role several times with different parameters. A Server API method can be invoked if there is at least one role assigned to the user that allows the execution of this method in the context the user tries to execute it.
There are no deny semantics - actions cannot be explicitly forbidden. The following roles apply to the Server API security model:
Read role: read [list_of(configuration)] | The read role allows the user read
data from the Server's configuration(s).
If no list of configurations is specified or the list is empy, the user is not allowed to read any configuration. A special value * (asterisk) can be specified for the list of configurations and this means that the user is allowed to read (through Server API calls) all configurations currently loaded by the Server. When the list of configurations is not null/empty and does not specify * the user is allowed to read only the configurations specified. The read role does not grant permission to start processes (AssemblyLines) or apply any changes to the Server and its configurations. For example: [ROLE]:read [CONFIG]:* |
Execute role: execute [ list_of(configuration [list_of(AssemblyLines)]) ] | The execute role gives the user permissions
to execute AssemblyLines.
If no list of configurations is specified or the list is empty, the user is not allowed to execute any AssemblyLine from any configuration. A special value * (asterisk) can be specified for the list of configurations and this means that the user is allowed to execute all AssemblyLines from all configurations. When the list of configurations is present and does not specify * the user is only allowed to start the processes from the configurations specified in the list. For each configuration specified in the list:
[ROLE]:execute [CONFIG]:C:/TDI/rs.xml [AL]:* [CONFIG]:C:/TDI/prototype.xml [AL]:TestAssemblyLine |
Admin role: admin | The admin role allows the user to execute
all Server API calls in every possible context.
A user with admin role is allowed to read and modify configurations, to load new configurations, to execute AssemblyLines, to read and modify server parameters. For example: [ROLE]:admin
Admin role is required to use the Remote Configuration Editor. Also see Using the Remote Configuration Editor. |
The values specified in a [CONFIG] tag can be either Config file names, or Solution Names if they have been specified in the Config file.
The User Registry, identified by the api.user.registry property in the global.properties or solution.properties file is a text file that maintains the information about all the users of the API and their roles. This file is encrypted with the Server's certificate specified by the api.key.alias property from the keystore specified by the api.keystore property. The encryption algorithm employed is Asymmetric RSA encryption or decryption; that is why the Example Server certificate creation specifying the RSA algorithm, which is the default algorithm of the The TDI Encryption utility provided with TDI that we can use for this purpose. On startup, the Server API engine decrypts and reads this file into its memory structures.
Notes:
The contents of the Identity Registry text file is structured as follows:
[USER] [ID]:<user_identifier> [ROLE]:<role_identifier> [CONFIG]:<config_identifier> [AL]:<assembly_line_name> [AL]:<assembly_line_name> ... [CONFIG]:<config_id> ... [ROLE]:<role_identifier> ... [ROLE]:<role_identifier> ... [ENDUSER] [USER] [ID]:<user_identifier> [ROLE]:<role_identifier> ... [ENDUSER] ...
Each tag must span a single line and each tag must be on a separate line. Tabs and spaces do not matter. Empty lines may appear anywhere. The tags in the Identity Registry file and their arguments are as follows:
Tag | Argument |
---|---|
[USER] | This tag takes no arguments, and serves as an opening bracket for the tags below; a [USER] and [ENDUSER] pair of tags, each placed on a single line, provide the definition of a single user in the registry file. There can be multiple pairs of this type, each of which specify a user of the Server API. |
[ID]:<user_identifier> | This tag is the first tag after the [USER] tag and its argument <user_identifier> is the unique identifier of the user of the Server API. This ID value is the *** from the truststore file. The tag and the argument of the tag are placed on a single line, and there can be only one [ID]: tag included in a [USER] and [ENDUSER] pair. |
[ROLE]:<role_identifier> | This tag specifies a role for the user. Possible roles are: read, execute or admin. Everything after the [ROLE]: tag and its argument and before another [ROLE]: tag or an [ENDUSER] tag (whichever comes first) specifies details of this user role. The tag and the argument of the tag are placed on a single line, and there can be multiple [ROLE]: tags included in a [USER] and [ENDUSER] pair, specifying multiple roles for that user. |
[CONFIG]:<config_id> | This tag specifies the identifier of a TDI configuration, the absolute file path of the configuration.
Relative file paths are not recognized. This tag is subordinate to
a [ROLE]: tag, and the tag specifies a configuration for
the role given by the [ROLE]: tag. This tag and its argument
are placed on a single line, and there can be multiple [CONFIG]: tags, all belonging to the superior [ROLE]: tag.
If no [CONFIG]: tag is associated with a [ROLE]: tag, the list of configurations for the corresponding role definition is empty. |
[AL]:<assembly_line_name> | This tag specifies an AssemblyLine name. This
tag is subordinate to a [CONFIG]: tag. The tag and its argument
are placed on a single line, and there can be multiple [AL]: tags, all belonging to the superior [CONFIG]: tag.
If no [AL]: tag is associated with a [CONFIG]: tag, the list of AssemblyLines for the corresponding configuration ID is empty. |
The following text is an example of an Identity Registry file:
USER] [ID]:CN=Stan, OU=TDI, O=IBM, C=US [ROLE]:admin [ENDUSER] [USER] [ID]:CN=John, OU=TDI, O=IBM, C=US [ROLE]:read [CONFIG]:* [ROLE]:execute [CONFIG]:C:/TDI/rs.xml [AL]:* [CONFIG]:C:/TDI/prototype.xml [AL]:TestAssemblyLine [ENDUSER] [USER] [ID]:CN=Peter, OU=TDI, O=IBM, C=US [ROLE]:execute [CONFIG]:C:/TDI/rs.xml [AL]:* [ENDUSER]
This set of Identity Registry entries implies the following constraints:
The keytool and/or the Ikeyman utility can be used to obtain the user ID from the truststore file. The following command line prints all users from the truststore file:
keytool -v -list -keystore <trust_store_file> -storepass <trust_store_pass>where <trust_store_file> is the keystore file that contains the certificates of all trusted users and <trust_store_pass> is the password for this keystore file. This command line prints something like the text below for each user certificate:
Owner: CN=Stan, OU=TDI, O=IBM, C=US Issuer: CN=Stan, OU=TDI, O=IBM, C=US Serial number: 408f6a34 Valid from: 4/28/04 11:24 AM until: 7/27/04 11:24 AM Certificate fingerprints: MD5: F6:EF:81:8B:4C:0F:10:E4:A0:16:99:AB:42:29:70:8B SHA1: FE:37:62:8B:42:2F:54:F8:F6:F3:FC:A1:DD:7D:2A:51:9A:85:09:02The value of the Owner field must be specified as value for the [ID]: tag in the Identity Registry as is, including all white space and commas. For this example, the line with the ID tag looks like:
[ID]:CN=Stan, OU=TDI, O=IBM, C=USAn alternative way to obtain the user ID from the truststore file is to use Ikeyman in the following way:
The TDI Audit Component enables the TDI Server to audit events such as authentication and authorization in the Server API.
Notifications are generated when authentication and authorization (auth*) events occur. Audit data is packaged into an Entry and provided as user data in the notification. The "Audit Service" consists of a separate Audit config that is automatically loaded by the TDI server. The Audit config contains auto-started Audit AssemblyLines. The Audit ALs iterate on the notification connector using suitable filters. TDI users can even generate "user defined notifications" if they want to create audit events from within their own code.
TDI auditing contains two main parts:
Generating necessary audit information is implemented by creating TDI Entries on each audit point in the Server API, and by broadcasting these Entries wrapped in a notification. For this purpose a new class is presented in the Server API (com.ibm.di.api.APIAuditor), that generates the Entry, attaches the Entry as UserData to a notification, and sends it to all interested listeners.
The "Audit Service" is the main consumer of the audit notifications. The Audit Service is a config consisting of several ALs that iterate on the Notification Connector. Using different filters can register to a variety of notification types.
The TDI audit capability follows only what people do, and does not follow Server events in general. There is a difference between a user being authorized to perform a task (stop an AL) and the task actually being performed (AL is terminated). Being authorized is an authorization event and the performing of a legal action, like stopping an AL, is a Server event. When a user instructs an AssemblyLine to stop and the AssemblyLine terminates, an authorization event is paired with a Server event. At other times, a Server event occurs by itself, as when an AssemblyLine completes naturally. Only events which involve direct user interaction are audited. This limits the default audit points to authentication and authorization events inside the Server API. Almost every method exposed by the Server API is protected by its own piece of authorization code. The Audit component does not try to send notifications for all authorization events, but selects a reasonable subset of authorization-guarded Server API methods. The principles for the selection are to audit all events that:
The TDI Server API allows certain notification types to be suppressed for improved performance. The notification framework does not propagate suppressed events. If you try to broadcast an event of a type suppressed, the Server API does not issue an error. However, the suppressed event cannot reach any of the registered notification listeners. The list of suppressed event types is configured by a system property named:
api.notification.suppress
By default, all authentication and authorization events are suppressed:
api.notification.suppress=di.server.api.authenticate di.server.api.authorize*
The event types in the list are separated by spaces. Wildcards matching multiple event types are allowed. If the event type property is missing or is empty, no events are suppressed. We can suppress all custom notifications by typing:
api.notification.suppress=user
Suppression affects the whole TDI Server and can result in suppression of all kinds of notifications. Even built-in notifications, such as an AssemblyLine starting or the Server shutting down, can be suppressed. Improper use of the suppression capabilities can interfere with the work of components that listen for notifications such as the Tombstone Manager and the Server Notifications Connector.
Sending notifications uses a method in com.ibm.di.api.APIEngine:
public static void sendNotification (String type, String id, Object data, String configInstanceId)
This method creates a DIEvent. By this means, a notification is delivered to every Listener registered to receive the a particular type of notification. Notification delivery parameters include:
Parameter name | Definition |
---|---|
type | Notification event type. |
id | Notification event ID. |
data | Notification event UserData object in the form of a Java object with additional information. |
configInstanceId | Notification ConfigInstance ID to which the notification is bound. |
The com.ibm.di.api.APIEngine method throws DIException if the type parameter is null. Calls to the method can be invoked either: