4

How do I expire the administrator session after a period of inactivity in SilverStripe 3.1.x? Is there a config option for this?

I searched and found the following code snippet, which, when placed in the Page_Controller class, works for frontend users, but totally ineffective in the administration area.

public function init() {
    parent::init();
    self::logoutInactiveUser();
}


public static function logoutInactiveUser() {
    $inactivityLimit = 1; // in Minutes - deliberately set to 1 minute for testing purposes
    $inactivityLimit = $inactivityLimit * 60; // Converted to seconds
    $sessionStart = Session::get('session_start_time');
    if (isset($sessionStart)){
        $elapsed_time = time() - Session::get('session_start_time');
        if ($elapsed_time >= $inactivityLimit) {
            $member = Member::currentUser();
            if($member) $member->logOut();
            Session::clear_all();
            $this->redirect(Director::baseURL() . 'Security/login');
        }
    }
    Session::set('session_start_time', time());
}

After over 1 minute of inactivity, the admin user is still logged in and the session has not timed out.

D-L
  • 255
  • 1
  • 15
  • The admin area will not use/call your controller so the init() method will never be called. Maybe for the CMS you can implement something in the canView hook or similar, but not sure that's the best solution... – colymba Jun 11 '14 at 10:41
  • I'm attempting to create an extension that adds an addtional method to the CMSMain class. Never done this before, but if it works, I'll post the solution here. – D-L Jun 11 '14 at 10:46

3 Answers3

3

For people like myself still searching for a solution to this, there's a much simpler alternative. As it turns out, the only good solution at the moment is indeed to disable LeftAndMain.session_keepalive_ping and simon_w's solution will not work precisely because of this ping. Also, disabling this ping should not cause data loss (at least not for SilverStripe 3.3+) because the user will be presented with an overlay when they attempt to submit their work. After validating their credentials, their data will be submitted to the server as usual.

Also, for anyone who (like myself) was looking for a solution on how to override the CMS ping via LeftAndMain.session_keepalive_ping using _config.yml keep reading.

Simple Fix: In your mysite/_config.php, simply add:

// Disable back-end AJAX calls to /Security/ping
Config::inst()->update('LeftAndMain', 'session_keepalive_ping', false);

This will prevent the CMS from refreshing the session which will naturally expire on it's own behind the scenes (and will not be submitted on the next request). That way, the setting you may already have in _config.yml dictating the session timeout will actually be respected and allowing you to log out a user who's been inactive in the CMS. Again, data should not be lost for the reasons mentioned in the first paragraph.

You can optionally manually override the session timeout value in mysite/_config/config.yml to help ensure it actually expires at some explicit time (e.g. 30min below):

# Set session timeout to 30min.
Session:
  timeout: 1800

You may ask: Why is this necessary?

Because, while the bug (or functionality?) preventing you from overriding the LeftAndMain.session_keepalive_ping setting to false was supposedly fixed in framework PR #3272 it was actually reverted soon thereafter in PR #3275

I hope this helps anyone else confused by this situation like I was!

Community
  • 1
  • 1
patricknelson
  • 977
  • 10
  • 16
2

This works, but would love to hear from the core devs as to whether or not this is best practice.

In mysite/code I created a file called MyLeftAndMainExtension.php with the following code:

<?php

class MyLeftAndMainExtension extends Extension {

    public function onAfterInit() {

        self::logoutInactiveUser();

    }


    public static function logoutInactiveUser() {
        $inactivityLimit = 1; // in Minutes - deliberately set to 1 minute for testing 
        $inactivityLimit = $inactivityLimit * 60; // Converted to seconds
        $sessionStart = Session::get('session_start_time');
        if (isset($sessionStart)){
            $elapsed_time = time() - Session::get('session_start_time');
            if ($elapsed_time >= $inactivityLimit) {
                $member = Member::currentUser();
                if($member) $member->logOut();
                Session::clear_all();
                Controller::curr()->redirect(Director::baseURL() . 'Security/login');
            }
        }
        Session::set('session_start_time', time());
    }

}

Then I added the following line to mysite/_config.php

LeftAndMain::add_extension('MyLeftAndMainExtension');

That seemed to do the trick. If you prefer to do it through yml, you can add this to mysite/_config/config.yml :

LeftAndMain:
  extensions:
    - MyLeftAndMainExtension
D-L
  • 255
  • 1
  • 15
  • Well...this solution satisfied PwC - they tested it and marked this medium-risk defect as "closed". If an admin user is inactive for 30 minutes (obviously, in the final solution, I changed the inactivity limit to 30 in the example above), then they are automatically logged out as a security measure. – D-L Jun 13 '14 at 14:36
1

The Session.timeout config option is available for setting an inactivity timeout for sessions. However, setting it to anything greater than 5 minutes isn't going to work in the CMS out of the box.

Having a timeout in the CMS isn't productive, and your content managers will end up ruing the timeout. This is because it is possible (and fairly common) to be active in the CMS, while appearing inactive from the server's perspective (say, you're writing a lengthy article). As such, the CMS is designed to send a ping back to the server every 5 minutes to ensure users are logged in. While you can stop this behaviour by setting the LeftAndMain.session_keepalive_ping config option to false, I strongly recommended against doing so.

  • If I had it my way, I would leave it as it is - I agree with you and it's good enough for me, however, I am forced to address this as a result of a client security scan by PwC - they flagged this as a medium risk security issue. Their recommendation is to timeout the admin session after 30 mins of inactivity. I have no choice in this matter. Thanks for taking the time to answer my query, though, much appreciated. – D-L Jun 11 '14 at 12:15