What is the best way from an admin to force a logo...
# lucee
l
What is the best way from an admin to force a logout of all users to an application (effectively forcing them to re-login at their next request)? The users are stored in J2EE sessions. Currently playing with this code, but is it safe/wise? Are there better ways to do it? FWIW, we're probably only talking about just a couple hundred users logged in at any given time.
Copy code
var userSessions = createObject( "java", "coldfusion.runtime.SessionTracker" ).getSessionCollection( application.applicationName );
userSessions.each( ( user ) => structClear( userSessions[ user ] ) );
s
are you opposed to restarting the server?
w
if the situation is you've made some change to a session object or session vars and you need everyone to login anew to pick up the changes, i'd have to go along with just recycling the server instance, simple and certain
z
this is what Micha has been planning to add to achieve just this! https://dev.lucee.org/t/applicationinvalidate-serverinvalidate/10985
r
This is why I also create a token in a database table for user logins. That way I can just invalidate those tokens and force a login for everyone.
l
@Scott Steinbeck thx. Would prefer not to cycle the whole server. Also, I think the article from @foundeo doesn't allow an admin to remotely invalidate multiple users' sessions? @websolete that's correct, adding new data to session objs that needs to be picked up, preferably on the next request. @Rodney how does that work exactly? Or are you having each user hit the db on every request? So is the use of the
"coldfusion.runtime.SessionTracker"
a bad or unsafe practice?
w
i like rodney's idea tbh. you have an application variable with a token, maybe something like
application.sessionControl = gettickcount();
that gets set during app init, then is propagated to the session onSessionStart(). in onRequestStart() you check if session.sessionControl == application.sessionControl you do nothing, if it's different you invalidate their session (and presumably redirect to login). all you'd need is some backend/admin way of updating application.sessionControl when you need to force users to relogin
i'm not sure it needs to come from a db, feels like gettickcount() persisting for the lifespan of the application would be fine, but maybe rodney has some specific experience that led him to store it in the db
r
@Scott Steinbeck Yes, it hits the database on every request but it's so fast it's negligible. You can also do what Kevin said. Depends on how much control you want. We do it at the user level so we can kill all of an individual user's sessions or everyone's sessions.
Well, technically the session still exists. It's just invalid to the application if the token doesn't exist for the user.
s
and implementation of pete’s solution is to set a date in the application scope and check to see if the session has that date and it matches otherwise invalidate their session, from the requestStart
then for future instances where token invalidation needs to happen, just update the date in the application scope
Copy code
function onRequestStart(){
   application.sessionStartDate = '2022-10-15';
   if(!structKeyExists(session,'sessionStartDate') || session.sessionStartDate != application.sessionStartDate){
     //invalidate token here
   }
}
something like that
w
So is the use of the
"coldfusion.runtime.SessionTracker"
a bad or unsafe practice?
it certainly was in the past, not sure what the prevailing sentiment is about it nowadays. back when it was thrown around it would grind miserably if you had anything more than 'a few' sessions, whatever that number was. it was just a costly/uncodumented way of 'managing' sessions
l
Thank you all! Yeah, I was looking at writing up something similar to the application scoped token to check per request - which would work great for logging out all users. But then when I found out about
coldfusion.runtime.SessionTracker
the wheels started turning because then I could also do things like manipulate data in an individual user's session scope remotely (e.g. add a new role/permission on next request, etc.)