Remember Me

80 views
Skip to first unread message

t.pickett66

unread,
Oct 3, 2012, 3:35:48 PM10/3/12
to rubycas...@googlegroups.com
Greetings all,
As I've indicated in previous posts my business requirements dictate that our SSO system support long sessions (a.k.a Remember Me). I've scoured the JA-SIG implementation and peaked at the previous suggestions regarding this issue on GitHub and recognize that not every one's use case allows this behavior. Unfortunately the previous attempt at this change didn't give any flexibility regarding the enablement/disablement of this feature leading to it not being accepted. The fork that contained this patch has been deleted so I don't really have a starting point to work from but from what was said it was a bit simplistic but a decent start.  In order to satisfy both use cases and enable other ticket expiration policies in the future I'd like to propose the following changes and receive feedback before I get too far into implementing them. This gist has some examples of how I think these things could be accomplished. Also any suggested deprecations in the config should target a 6-12 month timeframe before being dropped.
  • add DB field to 'casserver_tgt': expiration_policy (String)
    • the name of a class that defines the expiration time frame for the ticket
    • the default value could be nil to maintain compatibility with existing systems in operation
    • additional classes wouldn't be hard to define w/ a touch of meta programming based on the values put into the config file
  • add optional configuration 'expiration_policies'
    • see config.yml.erb in the gist
    • Currently I can only see RememberMe being used but we may run into additional cases
    • deprecate current way of top level specification for the maximum_session_lifetime
  • add XML notification to clients regarding remember me
    • should only get sent if remember_me is checked and allowed in the config
  • set cookie expiration policy for TGT cookie based on the expected session lifetime
  • have a checkbox show up if there is a RememberMeExpirationPolicy class present
  • set TGT's relations to include the option: dependent_destroy => true
    • so we don't have so many items to clean up later
I also don't really see where tickets are being cleaned up so I assume this is being handled for most users by some sort of external scheduling system like cron. So, I'd also like to add an example of how to do this or perhaps a rake task to handle this that could be run by the scheduler of choice.

t.pickett66

unread,
Oct 5, 2012, 11:38:24 AM10/5/12
to rubycas...@googlegroups.com
I've started working on this with a few changes based on some things I like about the JA-SIG implementation. My work can be found on GitHub at https://github.com/r2practice/rubycas-server/tree/remember-me there isn't much there yet but its coming along.

Matt Zukowski

unread,
Oct 5, 2012, 2:41:58 PM10/5/12
to rubycas...@googlegroups.com
Tyler just wanted to say I haven't had time to reply to this properly yet but I did read it and plan to write back. I'll be in touch soon.

--
You received this message because you are subscribed to the Google Groups "RubyCAS" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubycas-server/-/OFAYm46frCsJ.

To post to this group, send email to rubycas...@googlegroups.com.
To unsubscribe from this group, send email to rubycas-serve...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubycas-server?hl=en.

t.pickett66

unread,
Oct 12, 2012, 12:08:42 PM10/12/12
to rubycas...@googlegroups.com, ma...@roughest.net
Matt, I'm interested in hearing what you have to say.

As I've gone through and implemented this I've learned a lot about the reference implementation and raised several questions about solving the same problems in an idiomatically Ruby way. I've noticed that the method of expiring tickets is purely based on ticket creation time regardless of activity. So if the timeout is set to 2 days but the user only hits one page and leaves for the weekend they potentially have a session sitting there waiting to get taken over by someone with physical access to their machine. The reference impl handles this by having TGT's expire based on either absolute lifetime (Default: 8 hours) or activity (Default: 2 hours). Then for long session functionality the wiki sets up  the expiration policy purely based on the activity timeout but there isn't anything preventing an admin from using the dual absolute/activity timeout to force users to login every so often. With the expiration policy classes I've implemented so far we've only got one or the other available for any given situation but adding one that checks both isn't difficult. But all of this would require tracking user activity, something we don't currently have facilities for but shouldn't be difficult to add.

Something else I've noticed is that their consumable tickets get reaped on the next expiration sweep without looking at the timeout. This is done through a counter on the ticket for # of uses rather than an explicit consumed timestamp. The reason I mention this is that some use cases for the TGT could use this same functionality, it may fall into YAGNI but it may not.

Finally I've changed my approach to the problem based on what I've seen from the reference implementation and some of the issues they've had and some I could see coming up. Rather than storing the expiration policy class or any info about it in the DB a single now lives in a class level instance variable set at init time. The reference impl stores a serialized object in the DB as part of the ticket so each ticket has its own instance of the policy. There are a few problems I see with this:
  1. In the event we want to change the timeout policy for existing tickets there really isn't any way to without modifying EVERY ticket in the DB
  2. If a ticket gets assigned the NeverExpirePolicy it would have to be manually cleaned up.
  3. Each instance takes up some memory, while it is a small amount if you accidentally loaded 100k tickets at once it could add to the already severe problem
  4. Object instantiation takes time, while it doesn't take much why do it if we don't have to.
I don't know that they've ever seen #'s 1 or 2 being an issue but I know that the first one would be quite inconvenient. They do however have problems with #3 because of the way they iterate through all of the tickets to check that they are expired. Our current implementation would require this same iteration although if done in a sane way (find_each) it shouldn't kill a server. We could take advantage of ActiveRecord and have the ticket classes delegate the construction of some sql to their expiration policies enabling us to only grab the expired tickets much the same way they are currently handled in Ticket.cleanup(max_lifetime). To implement this in an easy way we'd probably need to break compatibility with ActiveRecord 2.3.x. Problem #4 isn't really likely to be a problem but on a busy system ever cycle counts so why waste them. This last point is taken care of by the use of class instance variables but AbstractExpirationPolicy.new also caches each instantiated policy (each class has its own cache) by timeout length so if we set all of the tickets to use DefaultExpirationPolicy with a 500 second timeout we'll actually only end up with one object that's shared between them all.

t.pickett66

unread,
Oct 17, 2012, 1:08:36 PM10/17/12
to rubycas...@googlegroups.com, ma...@roughest.net
For those not watching the github repo I've submitted an initial pull request for this feature for review. I'm working on cleaning up the commits and moving the ones not related to the feature to other branches/pull requests.
Reply all
Reply to author
Forward
0 new messages