Skip to Content

Background

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


Investigation


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)

/wp-content/uploads/2015/10/b1_802475.png


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 




Solution Design


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.

Implementation

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()

{

    CompositeData data[]=null;

    try

    {

    SessionManagementModel model = new SessionManagementModel();

     data = model.getSessions();

    }

        catch(Exception ex)

        {

// If this block gets executed, this means there are some problem accessing the session data.

          LOCATION.debugT(ex.getMessage());

          return false;

        }

    if(data!=null)

    {

    for(int i=0;i<data.length;i++){

    if(data[i].get(“UserName”).toString().equalsIgnoreCase(name)

    &&

    data[i].get(“RootContextID”) != null) // This is important as there can be non HTTP sessions which won’t have a context id assigned.

    {

    return true;

    //throwNewLoginException((new StringBuilder()).append(“Active session exists for user”).append(user.getName()).toString(), (byte)15);

    }

    }

    }

  return false;

}

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*/

    if(userHasActiveSession())

    {

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


/wp-content/uploads/2015/10/b2_802477.png


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.


<script type=”text/javascript”>

$(document).ready(function()

{

var $d = $(“.urTxtMsg”).text();

if (($d.length != 0)&& ($d == ‘Authentication failed. Client is already authenticated as a different user’)) {

$(“.urMsgBarErr”).hide();

$(“.urTxtMsg”).text(“New Session not allowed. You already have a running session!!”);

//alert(‘Cannot create new session. You already have a running session!!’);

  $(“.urTxtMsg”).dialog({

   title: “Error”

  });

}

});

</script>

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 😉

Tests



First Login

/wp-content/uploads/2015/10/b3_802496.png


Second Login Attempt


/wp-content/uploads/2015/10/b4_802497.png


Post Script


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.



Attachments

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.

https://www.dropbox.com/sh/etm97uvth0rcbsd/AAC4jOapeW7y4yaWiTC-ssrOa?dl=0

Final Words

Please leave your feedback in comments, bouquets or brick-bats all are welcome.

To report this post you need to login first.

11 Comments

You must be Logged on to comment or reply to a post.

  1. Ludwig Hofmann

    Hi,

    as I am not a developer, I cannot dive into that in details. but let me confirm, this is a real business requirement. Really strange that SAP has not realized this.

    good work!

    Ludwig

    (0) 
  2. Dheeram Kallem

    Hi Prashant,

    I did similar session management(just like SAP GUI session) in J2EE application 13 years back. Few years back I was researching to find a solution, but SAP said it’s not possible because of multiple application servers and nodes.

    With your POC, I’m confident it works. Thanks once again for sharing your finding.

    Regards,

    Dheeram

    (0) 
  3. sravan guttu

    Prashant,

    Do you think we can implement same functionality as SAP GUI to provide  the option  to kill the existing session and allow new session to logon. My client was asking for this requirement .

    Thanks,

    Sravan.

    (0) 
    1. Kumar Prashant Post author

      Hi Saravan,

      The answer is both yes and No.

      Technically there is a method called terminate. You can check the terminate function through NWA. What it does is it removes the entry from the bean, but as I mentioned in SAP Portal session and stickiness are handled through cookie, if the cookie is still active just by doing a refresh in browser the terminated session will again be established.

      Check the attached screenshots

      ~Prashant/wp-content/uploads/2015/10/an1_803510.png/wp-content/uploads/2015/10/an2_803511.png/wp-content/uploads/2015/10/an3_803512.png/wp-content/uploads/2015/10/an4_803513.png

      (0) 

Leave a Reply