re-initiating the login for a user who is already logged in

Post any questions you have about using the Verj.io Studio, including client and server-side programming with Javascript or FPL, and integration with databases, web services etc.

Moderators: Jon, Steve, Ian, Dave

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

re-initiating the login for a user who is already logged in

#1

Postby Segi » Fri Aug 24, 2018 10:00 pm

I have an admin app that I use to manage all of our users. The user database has a column called ReloadPermissionsAndRoles which is a BIT value.
Normally the value of this column is 0. After the user is given (or loses) access to an application or gets a new permission for an application, this column gets set to 1 to indicate that the users' perms and roles has changed and needs to be reloaded.

Every time that the user accesses an application, a globally shared function called verifyUserSession() is called in the before page event to make sure that the user is allowed to have access to the application. This application also checks to see if ReloadPermissionsAndRoles=1. If it is, it dynamically reloads the permission and what applications the user has access to by re-initiating the login process because the login is where the users' access and permissions are initialized. I do it this way because without re-initiating the login process, the user would have to log off and then log on again to make the changes in access go into effect and I don't want to have to have them do this.

In the logon service, this is how the users' access gets initialized

Code: Select all

// Get all the menus that this user is authorized for based on their user ID
          tables.GENERATE_USER_MENU.UserID.value=tables.USERS.USERID.value;
          tables.GENERATE_USER_MENU.fetchTable();

          if ( tables.GENERATE_USER_MENU.rowCount > 0 ) {  
               var allMenuRows=tables.GENERATE_USER_MENU;
               var menuRows=allMenuRows.getRows();

               while (menuRows.next()) {
               	    // Add the menu name to the custom roles so it can be used to determine whether a user has access to that menu
                    tables.CUSTOMROLES.insertRow();
                    tables.CUSTOMROLES.ROLEID.value=allMenuRows.MENUNAME.value;
                    tables.CUSTOMROLES.updateTable();
               }
          }

          // Get all of the users' permissions based on their user ID
          tables.Permissions.UserID.value=tables.USERS.USERID.value;
          tables.Permissions.fetchTable();

          var allPermissions=tables.Permissions;
          var allPermissionsRows=allPermissions.getRows();

          while (allPermissionsRows.next()) {
               tables.CREDENTIALS.insertRow();
               tables.CREDENTIALS.ID.value=allPermissions.PermissionName.value.toUpperCase(); // Instead of fixing all places that reference the check to see if the user has the permission, I make this upper case so its always consistent
               tables.CREDENTIALS.VALUE.value=(allPermissions.HasAccess.value==true ? 1 : 0);

               tables.CREDENTIALS.updateTable(); 
          }
To invoke the login process in verifyUserSession() when ReloadPermissionsAndRoles=1, I do

// Invoke the LOGON service
system.securityManager.logon([["",columnData.Username],["",columnData.Password]]);

This usually works except that lately I've had an issue lately where about every 1 in 10 times that I do this, the server locks up and stops responding and I have to restart the server.

I think that the User database is getting overwhelmed and cant accept new logins after a while.

Is there a better way to re-initiate the login process ?
0 x

ericb
Ebase User
Posts: 82
Joined: Fri Jan 15, 2016 2:34 pm

Re: re-initiating the login for a user who is already logged in

#2

Postby ericb » Tue Aug 28, 2018 2:28 pm

This isn't really a solution for your problem, but just my thoughts;

Does a user's roles and permissions change so often that requiring them to log in again after they change is a major inconvenience? If not, I would consider changing the logic so that when ReloadPermissionsAndRoles == 1, just force a log-off and bring them to the log in page. You could display a message such as "Your access levels have been updated, please log in again".

Like I said, this doesn't actually fix your problem, but assuming the server lockup is only happening because of the auto-login you're trying to do, it does get around the problem.
0 x

Steve
Moderator
Moderator
Posts: 414
Joined: Fri Sep 07, 2007 3:44 pm
Location: Sandy, UK
Contact:

Re: re-initiating the login for a user who is already logged in

#3

Postby Steve » Wed Aug 29, 2018 11:03 am

Hi Segi,

Just one thing to note. You do not need to call updateTable in the loop of the menuRows.next() or the allPermissions.next() loops. Put the updateTable outside the loop. This will not fix your problem though.

In version 5.3 there is a new function to update the user roles and credentials without the need to logon again:

Code: Select all

 try {
   system.securityManager.updateLoggedOnUser( fields.USER.value, [
          ["Update", fields.USER.value]
         ] );
 }
 catch (e) {
   event.owner.addErrorMessage(e.javaException.message);
 }
Kind regards

Steve Upton
0 x

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

Re: re-initiating the login for a user who is already logged in

#4

Postby Segi » Wed Aug 29, 2018 3:45 pm

Steve,

I'm assuming that you meant 5.4. What is the ETA for 5.4 ?
0 x

Steve
Moderator
Moderator
Posts: 414
Joined: Fri Sep 07, 2007 3:44 pm
Location: Sandy, UK
Contact:

Re: re-initiating the login for a user who is already logged in

#5

Postby Steve » Thu Aug 30, 2018 10:20 am

No, I meant 5.3 as that is what the documentation states.

You can download version 5.3.2 from the Verj website: http://verj.io

Kind regards

Steve Upton
0 x

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

Re: re-initiating the login for a user who is already logged in

#6

Postby Segi » Thu Aug 30, 2018 2:45 pm

Steve,

I'm already on 5.3.2. I didn't realize that this was added in 5.3.2. I'lll try it out

Thanks
0 x

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

Re: re-initiating the login for a user who is already logged in

#7

Postby Segi » Tue Sep 11, 2018 6:37 pm

Steve,

I tried this out and the login script is not getting initiated again. This is how I am doing it:

Code: Select all

 function (columnData) {
          username=columnData.Username;
          
          try {
                     system.securityManager.updateLoggedOnUser(username,[["Update",username]]);

                    alert("Setting reload perms for " + system.securityManager.getCredential("REALNAME") + " and validation is " + system.securityManager.hasRole(MenuName));
                    event.stopExecution();
               } catch (e) {
                    // Parse the error message 
                    var errormsg=String(e);
     
                    // Remove this string from the beginning of the error message
                    errormsg=errormsg.substring("JavaException: com.ebasetech.xi.exceptions.LogonException: ".length);
                         
                    print("Error reloading permisssions and roles: " + errormsg + " when the logon username is " + columnData.Username);
                         
                    alert(errormsg);
     
                    event.stopExecution();
});
The alert in try should print true if the login has been reinitiated but its printing false

If this is really supposed to re-initiate the login as you said, then this code in the login service script would have executed:

Code: Select all

// Get all the menus that this user is authorized for based on their user ID
          tables.GENERATE_USER_MENU.UserID.value=tables.USERS.USERID.value;
          tables.GENERATE_USER_MENU.fetchTable();
print("GENERATE_USER_MENU RC=" + tables.GENERATE_USER_MENU.rowCount );
          if ( tables.GENERATE_USER_MENU.rowCount > 0 ) {  
               var allMenuRows=tables.GENERATE_USER_MENU;
               var menuRows=allMenuRows.getRows();

               while (menuRows.next()) {
               	   if (allMenuRows.MENUNAME.value=="GMS Holidays")
               	   
               	    // Add the menu name to the custom roles so it can be used to determine whether a user has access to that menu
                    tables.CUSTOMROLES.insertRow();
                    tables.CUSTOMROLES.ROLEID.value=allMenuRows.MENUNAME.value;
                    tables.CUSTOMROLES.updateTable();
               }
          }
The print statement isn't appearing in the server logs so it is not reinitiating the login.

If I change

Code: Select all

 system.securityManager.updateLoggedOnUser(username,[["Update",username]]);
to

Code: Select all

system.securityManager.logon([["",columnData.Username],["",columnData.Password]]);
the print statement in the login service does print out correctly.
0 x

Jon
Moderator
Moderator
Posts: 1342
Joined: Wed Sep 12, 2007 12:49 pm

Re: re-initiating the login for a user who is already logged in

#8

Postby Jon » Wed Sep 12, 2018 7:52 am

The "Update" string is just an example. This parameter is passed into the Logon Service as field PARAM1_SOURCE and allows you distinguish between a logon and an update if you need to do this. If it's not working and no error is thrown, the most likely cause is that your logon service script is checking field PARAM1_SOURCE and ignoring the value "Update".
0 x

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

Re: re-initiating the login for a user who is already logged in

#9

Postby Segi » Wed Sep 12, 2018 3:16 pm

Jon,
There aren't any references anywhere to PARAM1_SOURCE in my login script.

I'm not sure if what I said in my previous post was clear but what i was trying to explain is that I have a print statement in the login script that is not getting executed when I reinitiate the login using the call to updateLoggedOnUser() but does get executed when I call the method logon()
0 x

Jon
Moderator
Moderator
Posts: 1342
Joined: Wed Sep 12, 2007 12:49 pm

Re: re-initiating the login for a user who is already logged in

#10

Postby Jon » Wed Sep 12, 2018 5:00 pm

And presumably updateLoggedOnUser() is also not working i.e. it's not doing what it's supposed to do? That's what I understood you to mean.

Note that method updateLoggedOnUser() does nothing if the userid passed is not currently signed on - if this happens it won't even call the Logon Service.
0 x

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

Re: re-initiating the login for a user who is already logged in

#11

Postby Segi » Wed Sep 12, 2018 5:20 pm

Jon,

That is correct. The logon service is not getting invoked when calling updateLoggedOnUser().

This logic is being run while the user is already signed in

The userID that I am passing is the username.

The code for the login script that authenticates the user is here: https://pastebin.com/8nVtZpHF. The username comes from PARAM1_VALUE and the password comes from PARAM2_VALUE
0 x

Jon
Moderator
Moderator
Posts: 1342
Joined: Wed Sep 12, 2007 12:49 pm

Re: re-initiating the login for a user who is already logged in

#12

Postby Jon » Thu Sep 13, 2018 1:30 pm

Could you check the session listener is configured in the web.xml file in <webapp>/WEB-INF:

Code: Select all

<listener>
     	<listener-class>com.ebasetech.ufs.licence.SessionMonitor</listener-class>
</listener>
0 x

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

Re: re-initiating the login for a user who is already logged in

#13

Postby Segi » Thu Sep 13, 2018 2:59 pm

Jon,

Yes I do have this sessionmonitor entry on line 97 of web.xml
0 x

Jon
Moderator
Moderator
Posts: 1342
Joined: Wed Sep 12, 2007 12:49 pm

Re: re-initiating the login for a user who is already logged in

#14

Postby Jon » Fri Sep 14, 2018 3:13 pm

I tried updateLoggedOnUser() on my system and it all worked fine. I have logInfo turned on (System Admin > General Properties) and I see the Logon Service executing in the log:

Fri Sep 14 15:58:01: INFO ** START EXECUTION OF INTEGRATION FORM crmLogon1 **
Fri Sep 14 15:58:01: INFO Running Integration event for crmLogon1
Fri Sep 14 15:58:01: INFO Executing Javascript script crmLogonService1
Running Logon Service
Fri Sep 14 15:58:02: INFO ** END EXECUTION OF INTEGRATION FORM crmLogon1 **

I suspect that it's probably running on your system as well. Is it possible that the print command isn't being executed because you haven't passed in the password and therefore the code is taking a different root? The example shows "Update" being passed in the first parameter - the idea being that you check for this in the logon service and then skip the user validation part and only execute the reload of any credentials and roles.
0 x

Segi
Ebase User
Posts: 649
Joined: Mon Dec 09, 2013 6:37 pm

Re: re-initiating the login for a user who is already logged in

#15

Postby Segi » Fri Sep 14, 2018 5:25 pm

Jon,

I just tested this out. Right before the call to updateLoggedOnUser, I added a print statement

Code: Select all

     print(new Date().toTimeString().toString().substring(0,8) + " Initiating login");
     system.securityManager.updateLoggedOnUser(columnData.Username,[["Update",columnData.Username]]);
I also added a print statement at the very top of the login service script before anything else executes.

[code
print(new Date().toTimeString().toString().substring(0,8) + " Starting login process");
][/code]

When you login into the system normally, the "Starting login process" message is printed correctly to the server log.

In the server side function that calls updateLoggedOnUser to reload the permissions, which I pasted above, it does print Initiating login but does not print Starting login process which seems to indicate that the login just is not getting invoked. Again, the login service print statement is printed before any conditional logic.
0 x


Who is online

Users browsing this forum: No registered users and 6 guests