Forum OpenACS Q&A: How to expire session on the server side?

Request notifications

Does anyone know how I can expire a valid session of a logged in user on the server side so that if the user interacts again with oacs he/she is forced to login again?

The problem is that the users browser still stores valid cookies.

Collapse
Posted by Dave Bauer on
This procedure sec_change_user_auth_token http://openacs.org/api-doc/proc-view?proc=sec_change_user_auth_token claims to expire the cookies but Nima told me in IRC that it didn't do the trick.
Collapse
Posted by Torben Brosten on
Hi Nima,

Looks like ad_user_logout and ec_user_session_logout show how to set the cookies.

cheers

Collapse
Posted by Torben Brosten on
If you mean to logout a user where the procedure is initiated outside of the user's browser's server connection, then..

maybe the procedure can be passed to the user's next pageload via a noquoted util_user_message (or a new proc that works similarly).

Collapse
Posted by Nima Mazloumi on
excellent idea. works like a charm. but needs to extend acs-tcl package. I guess I have to create a tip.
Collapse
Posted by Torben Brosten on
force_logout_user is a feature that's been inquired about (and required by a few larger projects) over the years. Please do add the feature. Tip it if necessary.
Collapse
Posted by Dave Bauer on
I think it makes more sense to invalidate the cookies on the server side, this will ensure ALL cookies no matter where they are stored are invalid. This requires that whatever token is compared on the server is invalidated so the next time the cookie is used it is invalid.

This is already how expiring sessions work so it should not be difficult to make sure the existing cookie handling code does this.

Torben, I am not aware of any large project requesting this. Can you explain further?

Collapse
Posted by Dave Bauer on
This procedure sec_change_user_auth_token changes the user_id's auth token on the serveren the login cookie is checked it is validated against this token. This should do exactly what you want simply.

If that is not working, please investigate and help us fix it.

Collapse
Posted by Torben Brosten on
Hi Dave,

Without searching for irc chats on the subject, basically I recall 2 situations

First, a project requirement, such as in ecommerce, banking, commercial LAN environments, very public portals that host controversial topcis etc require a user's session to be immediately terminated on request.

Second is this:

Some admins increase the values of LoginTimeout, SessionLifetime, SessionRenew,SessionSweepInterval,SessionTimeout kernel parameters to reduce load, increase usability (require re-login less frequently etc), especially where trusted users are fairly stable after login and system resources are limited.

Anyway, the problem is that at some point, a user gets banned, but then it takes much much longer for the session to expire etc, meanwhile the user is having unauthorized access to the system and may be doing harmful actions.

One way to handle this would be lowering the values, restarting the server, waiting for the user to hopefully use each of the different browser sessions that might be open, and then reset the kernel parameters again and restart the server.. and praying that *all* the banned user's sessions are logged out.

A force_user_logout proc would fix these scenarios.

Collapse
Posted by Torben Brosten on
by "2 situations" I mean a repeating pattern of 2 situations over the years.
Collapse
Posted by Nima Mazloumi on
Emma: there is a single sign out solution. please take a look at auth-cas package. It has support for CAS 1.0 and 2.0 and yes, it is implemented as a authentication driver.

Dave: "Have you fully analyzed the cookie validation process to be sure there is no way to make it work with the already existing code?" Yes I have. But I will take another look just to make sure.

Dave: "One question on logging out users is whether they can be logged in to two computers and what happens if they log out on one of them." This is not supported in CAS. CAS is based on cookies. Thus it won't even work if you have two different browsers on a computer. CAS is only meant for the scenario where you are working on one computer with one browser but serveral systems and you want to make sure that once you log in you log into all those systems and once you logout you are logged out from all of them. Support for cross-browser and -computer scenarios go beyond that specification.

Stefan: "What happens if the the session time-outs just at the moment the reconnect happens?). Or, in the meantime, till the session is invalidated, she will appear as registered user though a third system induced her immediate log-out". CAS only works correctly if all systems have the same session lifetime. So it really doesnt matter if you cannot perform the reconnect because your session times out, because it times out for all systems. Your second example can never happen: If a user logs into system 1 via CAS and then logs out via CAS. CAS will request system 1 to logout the user next time he accesses system 1. Now if the user logins to system 2 via CAS first and goes back to system 1 he is logged out but forwarded immediately to CAS. Since the user has a fresh ticket he is redirected back to system 1 and logged in again. Thus the user is never logged out from system 2.

Again: cross-browser and cross-computer log in and log out is beyond CAS.

The one important thing is that during a logout CAS notifies all third systems to logout the user. If we have a cookie based system this won't work. Because the browser cookie of the user is not invalidated by the system since the system is notified by CAS on the server side. Therefore you have to make sure you invalidate the users cookies on the next request.

Collapse
Posted by Dave Bauer on
Nima said: "The one important thing is that during a logout CAS notifies all third systems to logout the user. If we have a cookie based system this won't work. Because the browser cookie of the user is not invalidated by the system since the system is notified by CAS on the server side. Therefore you have to make sure you invalidate the users cookies on the next request. "

This will work. The cookies are invalidated on the server side. Each cookie is hased with an authentication token. The token on the sever side is changed by sec_change_user_auth_token which means the next time the cookie is checked, it will not match and the user will be forced to login. Note the documentation string "Change the user's auth_token, which invalidates all existing login cookies." If this doesn't work, its a bug in OpenACS and should be fixed.

Collapse
Posted by Torben Brosten on
Dave writes "..the next time the cookie is checked..".

The force_logout_user code is really about requiring the key to be checked on the next page load.. regardless of when "the next time the cookie is checked" at some point in the future.

In essence, the job/task could be something like:

ad_user_logout
ad_script_abort

Collapse
Posted by Dave Bauer on
The cookies are sent on every request. As long as the request requires login, the cookie with be compared with the users token and the cookie will be invalid and they will be required to login again.
Collapse
Posted by Dave Bauer on

Phew! I that I was going crazy.

        if { $session_expr - [sec_session_renew] < [ns_time] } {

            # LARS: We abandoned the use of sec_login_handler here. This lets people stay logged in forever                                                    
            # if only they keep requesting pages frequently enough, but the alternative was that                                                                
            # the situation where LoginTimeout = 0 (infinte) and the user unchecks the "Remember me" checkbox                                                  
            # would cause users' sessions to expire as soon as the session needed to be renewed                                                                
            sec_generate_session_id_cookie
        }

This code breaks the sec_change_user_auth_token because it never checks the login auth_token if your session has not expired.

So I lose :) But it is a bug in the sec_handler not in sec_change_user_auth_token. I suggest we fix this instead of some magic code that runs on a future request.

Collapse
Posted by Torben Brosten on
Great!

I added some plain English translation to sec_change_user_auth_token to make it easier for admins like me to find it when we need to.

cheers!

Torben