Restrict Multiple sessions of same UserID in Portal
In my recent project one of the Non functional requirements is to control the number of sessions a user can have, i,e if an user already has a session in portal a new session with the same userid shouldn’t be allowed.
As per SAP Note 2052515 the one line answer is It is not possible to avoid multiple logons with the same user.
This really stumped me as it is one of the key requirements with some financial implications. I can’t spell the details as it’s a confidential information.
Like all SAP Consultants we have forwarded this note to the client and have requested to handle this requirement outside portal (RSA Token etc).
I still believe handling it outside portal is a better solution but since I investigated this problem in some detail I would like to share my POC.
Let me make it clear from the outset that this solution uses Undocumented APIS,.
While Searching on Google and SDN I came across many threads where people want to implement this, but at all the places the discussion ends with it’s not a valid business requirement. Let me assure you it is ???? .
While investigating this, I came across the NWA functionality Session Management (Resource Consumption)
As you can see the WD JAVA application is showing the session information. I still had my doubts w.r.t what will happen in a Clustered environment.
Like all developers I have a single node installation and I was not sure whether this application can show login details on multiple nodes in a cluster.
I confirmed this in the Preproduction environment in my client landscape that this application indeed shows sessions across nodes in a cluster.
I cannot share those screen shots as those are from client landscape but trust me it does ???? .
Locating the DC (sap.com/tc~lm~itsam~ui~session~mngt~wd) and the jar (sap.com~tc~lm~itsam~ui~session~mngt~wd) was not very difficult but analysing it was a tedious task.
If you decompile the jar ,( Refer to my earlier blog Getting started with Netweaver 7.3 portal Part 2 – NWDS and Logon Page to know how to use jadeclipse.) you will find a number of classes. SessionMngt , SessionMngtView and SessionManagementModel are the key classes.
I also found some useful information here:
Get list of all Logged in Users in SAP Netweaver 7.3
Since my requirement is to stop the user from login if the same userid already has a portal session, I wanted to implement this in login module.
Here is what I planned:
1. Create a login module
2. Using the above API, check if an user has a HTTP session (Note that the user can have a P4 session also) don’t allow him to login.
3. Modify the login page to show an appropriate error message.
Please refer to my earlier blog on login module and it’s implementation Getting started with Netweaver 7.3 portal Part 3 – Logon Language and Login Module
I decompiled the BasicPasswordLoginModule and used the decompiled code to build my own login module.
I have added one method to check if the user already has a session.
public boolean userHasActiveSession()
SessionManagementModel model = new SessionManagementModel();
data = model.getSessions();
// If this block gets executed, this means there are some problem accessing the session data.
data[i].get(“RootContextID”) != null) // This is important as there can be non HTTP sessions which won’t have a context id assigned.
//throwNewLoginException((new StringBuilder()).append(“Active session exists for user”).append(user.getName()).toString(), (byte)15);
This method is called after the user has been authenticated successfully (You don’t want to show the error if someone is not entering right credentials).
/* To determine if there is already an active session*/
//User already has an open session. Don’t let him login.
// The message here doesn’t make any difference, it gets overwritten by the messages in the jars.
throwNewLoginException((new StringBuilder()).append(“Active session exists for user”).append(user.getName()).toString(), (byte)15);
/* Continue with life as usual*/
In case you have a prior experience with Login Modules you will know that The way SAP has developed it the error messages come from a JAR file and it’s an error prone and tedious process to modify those jars and place it at server level.
Most amusing part is the method throwNewLoginException() takes a parameter of type String but doesn’t make any use of it decompile the class com.sap.engine.interfaces.security.auth.AbstractLoginModule and see it yourself!!.
The only field it makes use of is the byte field. Now for same strange reason only a predefined numbers are allowed, so there is no extensibility here, Say with me Bad Design.
These predefined values are stored in the interface com.sap.engine.lib.security.LoginExceptionDetails.
I choose 15 as it resembles the situation I am handling.
public static final byte USER_ALREADY_LOGGED_IN = 15;
After I deployed my login module and tested it. I didn’t get the expected result. I was able to open multiple sessions.
After checking the logs I found that the Guest user doesn’t have permission to access the Bean.
Below action needs to be assigned to the Guest user for this code to work.
With the Standard Login Page I got an in-line Error message, while trying to open another session
Authentication failed. Client is already authenticated as a different user
Not the message I was looking for.
I implemented my custom message using JQUERY and modifying the logonPage.jsp.
Not very elegant, as we are doing a String comparison with a harcoded value. This will fail if user language is not English but hey this is just a POC ????
Second Login Attempt
As I mentioned, This blog is result of a POC. It’s not a full blown/tested/live solution. Some key things to keep in mind:
1. Since HTTP is a stateless protocol the session management and session stickiness is implemented through cookies in SAP Portal. That’s why if you are running a portal session in a browser say IE and open a new tab with the portal URL it won’t be considered as a new session.
2. Consider a scenario where a User A accidentally closes the browser window, the server will not know that the session has been closed and it will not allow a new session for the same user till the session times out or an administrator closes the session.
3. I have not tested this solution in a clustered environment yet for obvious reasons (Need approvals etc). If someone can test and update it will be great. Incase I ever implement this in client environment I will update this blog.
The sca export can be downloaded from the dropbox link. It has got all the Development components needed for this blog. You can import the sca in your NWDS and play around with it.
Please leave your feedback in comments, bouquets or brick-bats all are welcome.