IBM Support

Login and Logout User Exits in SB2Bi 5.2.5/5.2.6 FixPack

Technical Blog Post


Abstract

Login and Logout User Exits in SB2Bi 5.2.5/5.2.6 FixPack

Body

I had put a blog in 2015 on how FTP/SFTP Server (Adapters) User Exits can be implemented and used in product. Lately I am seeing clients wanting to know about User Exits for Login and Logout in SB2Bi product. I am going to present useful information pertaining to it in this new blog.

Like SFTP Server Adapter User Exists, Login (Authentication) User Exits were introduced in product with FixPack 5.2.5.0 for first time. Where as Logout User Exits were released in 5.2.6.0. These Login and Logout User Exits follow the same framework as adapters'. Knowing one would make it easy to use other.

 

Note : Login User Exits apply to all authentications, like FTP, SFTP, dashboard, mailbox, HTTP etc, in product. Same is NOT true with Logout User Exits as it is limited to interfaces such as dashboard, filegateway, myfilegateway.

 

Availability of User Exit points is nothing but Java Interfaces are made available for users' custom implementations based on requirement.

 

Login User Exits in 5.2.5.0 and corresponding Java Interfaces: (Added in 5.2.5.0 FP)

Pre Authenticate - com.sterlingcommerce.woodstock.userexit.services.userlogin.interfaces.IUserLoginUserExit_preAuthenticate

This interface is hooked into the place just before authentication takes place for user credentials. And any custom definition that is given to to this interface would be triggered when user is logging into application and just before user's authenticity is verified. Hence it allows you to fail authentication for a user.

Post Authenticate success - com.sterlingcommerce.woodstock.userexit.services.userlogin.interfaces.IUserLoginUserExit_postAuthenticateSuccess

This is for Post authentication and when user is authenticated successfully. You could use this for use cases like maintain record keeping activities after user is successfully authenticated.

Post Authenticate failure - com.sterlingcommerce.woodstock.userexit.services.userlogin.interfaces.IUserLoginUserExit_postAuthenticateFail

This is for Post authentication and when user authentication is failed.

Logout User Exit in 5.2.6.0 and corresponding Java Interface: (Added in 5.2.6.0 FP)

Pre Logout - com.sterlingcommerce.woodstock.userexit.services.userlogout.interfaces.IUserLogoutUserExit_beforeSessionDestroyed


Java Doc APIs for these interfaces are available under install/userexit/docs folder as jar file (userlogindocs.jar & userlogoutdocs.jar)

 

Sample User Exit Implementation for IUserLoginUserExit_preAuthenticate

1) Scenario is to prevent a user from being authenticated if it is one from the given list (predetermined).

2) Understand this Java Interface to know what it has and offers.

From Interface API doc, I could see that it has exposed one API and it needs to be implemented with custom code for this scenario and hoot it back into product.

Looking at this API, it takes 2 arguments both of them are java.util.Map and one for input other is output.

+ input argument map has one entry "dataBean" and is object of Java Class (com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean)

+ output argument map has 2 entries for buffers (error and log)

image



Since Documentation for UserLoginDataBean is not bundled with API jar, let me explain a way to know APIs in this java class (any class in general) using java reflection. This is the sample Java class using reflection and it takes Class name and provide list of APIs in it back.

import java.lang.reflect.Method;

public class KnowYourClass {
//com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean

 

public static void main(String[]a) throws Exception {

Class cs = Class.forName(a[0]);
System.out.println("\nList of Methods from Class : " + a[0]);
int c = 1;
for (Method method : cs.getDeclaredMethods()) {
System.out.println(c++ + "." + method.getName() + " -> " + method.toString());
}
}
}

Compile and run it with class name as argumet. I used JDK on Linux for this.

$ javac KnowYourClass.java

$ ls Know*
KnowYourClass.java KnowYourClass.class

$ java -cp /install/userexit/jars/userlogin.jar:/install/jar/platform_ifcbase/1_3/platform_ifcbase.jar:. KnowYourClass "com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean"

Output
List of Methods from Class : com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean
1.getUserID -> public java.lang.String com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.getUserID()
2.getPassword -> public java.lang.String com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.getPassword()
3.isSSO -> public boolean com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.isSSO()
4.getAuthObj -> public java.lang.Object com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.getAuthObj()
5.getAddress -> public java.lang.String com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.getAddress()
6.setUserID -> public void com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.setUserID(java.lang.String)
7.setPassword -> public void com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.setPassword(java.lang.String)
8.setSO -> public void com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.setSO(boolean)
9.setAuthObj -> public void com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.setAuthObj(java.lang.Object)

10.setAddress -> public void com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean.setAddress(java.lang.String)

3) Come up with custom implementation for the Interface for this given scenario in #1.

Following class "LoginUEIBMTest.java" uses above high-lighted APIs (getUserID()) from dataBean object to obtain loginName (username). And compares it with user entries listed in /tmp/myLoginUserExit.properties. If current loginName is one listed in it, user would fail to authenticate.

Sample myLoginUserExit.properties (list of users that should be denied authentication)

$vi /tmp/myLoginUserExit.properties

denyUsers=user1, user2, user3 , user4, user5, user6

package kk.ue.login;

import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import java.io.FileInputStream;
import java.util.Properties;
import com.sterlingcommerce.woodstock.userexit.services.userlogin.interfaces.IUserLoginUserExit_preAuthenticate;
import com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginDataBean;

 

public class LoginUEIBMTest implements IUserLoginUserExit_preAuthenticate {

static String CLASS_NAME = "LoginUEIBMTest";
List<String> userList = new ArrayList<String>(10);
static String propFile = "/tmp/myLoginUserExit.properties";
private UserLoginDataBean dataBean = null;

 

private void loadDenyUserList() {

try {
Properties p = new Properties();
p.load(new FileInputStream(propFile));
System.out.println(CLASS_NAME + " - blocked user list from " + propFile);
p.list(System.out);
String denyUsers = p.getProperty("denyUsers");
String userArray[] = denyUsers.split("\\s*,\\s*");
for(String u : userArray) {
userList.add(u.trim());
}
System.out.println(CLASS_NAME + " - Authentication would be denied for following users : " + userList);
} catch(Exception e) {
e.printStackTrace(System.out);
}
}

@Override
public boolean preAuthenticate(Map<String, Object> inargs, Map<String, Object> outargs) throws Exception {
System.out.println(CLASS_NAME + " preAuthenticate");

dataBean=(UserLoginDataBean)(inargs.get("dataBean"));
String user = dataBean.getUserID();
System.out.println(CLASS_NAME + " preAuthenticate credentials : " + user+ " & "+dataBean.getPassword());
outargs.putAll(inargs);

loadDenyUserList(); //load list of users from properties file

if(userList.size() > 0 && userList.contains(user)) {

System.out.println(CLASS_NAME + " preAuthenticate fail user Login for " + user);
outargs.put(IUserLoginUserExit_preAuthenticate.KEY_ERROR_BUFFER, "Disallowed User \"" + user + "\"");
outargs.put(IUserLoginUserExit_preAuthenticate.KEY_LOG_BUFFER, "Disallowed User \"" + user + "\"");
System.out.println("inargs " + inargs);
System.out.println("outargs " + outargs);

return false;
}
return(true);
}
}

Compile, Build and make jar for this class definition.

$ javac -cp /install/userexit/jars/userlogin.jar:/install//jar/platform_ifcbase/1_3/platform_ifcbase.jar -d . *.java

$ jar cvf UserExitsIBMlogin.jar kk*

4) Plug in this jar with SB2Bi product.

+4.1 Add custom class name from #3 into install/properties/userexit/UserLoginUserExits.xml under corresponding user exit bean tag.

<bean id="com.sterlingcommerce.woodstock.userexit.services.userlogin.interfaces.IUserLoginUserExit_preAuthenticate_Test"
class="com.sterlingcommerce.woodstock.userexit.services.userlogin.UserLoginUserExit">
<property name="implementations">
<list>
<value>kk.ue.login.LoginUEIBMTest</value>
</list>
</property>
<property name="generalParameters">
<props>
<prop key="return.on.exception">false</prop>
<prop key="pool.size">10</prop>
<prop key="maximum.queue.length">10000</prop>
<prop key="wait.time">10</prop>
<prop key="execution.threshold.time">600000</prop>
</props>
</property>
</bean>

Note - Changes to this xml won't survive with upgrade/fixpack installation. They need to be re-configured.

+4.2 Plug in jar file from #3 to SB2Bi using install3rdParty.sh script. This adds VENDOR_JAR entry to properties/dynamiclcasspath.cfg and properties/dynamiclcasspathAC.cfg (for containers)

e.g., ./install3rdParty.sh userexitLogin 1_0 -j <path>/UserExitsIBMlogin.jar

5) start SB2Bi to take all these changes effective.

TESTING and screens

Try to login to dashboard UI with "user3" account. You will notice failure.

userexit.log in DEBUG mode would capture these details. It helps to ensure custom class is properly plugged in.

image

noapp.log.datetime file captures all System.out lines from LoginUEIBMTest.java

image


Post your questions, comments, feedback below.

 

[{"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SS3JSW","label":"IBM Sterling B2B Integrator"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB59","label":"Sustainability Software"}}]

UID

ibm11120941