Search code examples
sessionjsf-2primefacessession-timeoutshiro

JSF change session time out in shiro


I need to change the default session time out in my jsf application that uses shiro for security and session management. It defaults to 30 minutes.

Following is my shiro configuration

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
    <init-param>
        <param-name>config</param-name>
        <param-value>
        [main]

        authc = com.foo.bar
        authcRealm = com.foo.barAuthenticatingRealm
        sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
        securityManager.sessionManager = $sessionManager
        securityManager.sessionManager.globalSessionTimeout = 20000

        unAuthc = com.foo.UnauthorisedFilter



        /** = authc

        </param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

On using the above config, I am logged out immediately on login. Removing the following lines defaults the timeout to 30 mins

        sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
        securityManager.sessionManager = $sessionManager
        securityManager.sessionManager.globalSessionTimeout = 20000

Solution

  • Well after trying to search on the net and failing, and failing here too, I finally managed to find a way (sort of hack and not the best way). Here it goes

    Shiro by default creates a security manager of the type DefaultWebSecurityManager, so went ahead to extend it. Intercepted its createSubject() method and set the timeout there as follows

    public class SecurityManager extends DefaultWebSecurityManager {    
        @Override
        public Subject createSubject(SubjectContext subjectContext) {
            Subject subject = super.createSubject(subjectContext);
            subject.getSession().setTimeout(10 * 60 * 1000);
            return subject;
        }
    }
    

    Then assigned this SecurityManager to sessionManager (Very strange why they call a security manager a session manager, i wasted a lot of time before figuring this out) in the config as follows

    [main]
    authc = com.foo.bar
    authcRealm = com.foo.barAuthenticatingRealm
    sessionManager = com.foo.securityManager
    unAuthc = com.foo.UnauthorisedFilter
    /** = authc
    

    I don't think this is the only way to do it, I am sure there are much better ways, probably less hacky, better performant, but this worked for me, without any noticeable performance hit (though I did observe this method getting called several times, probably once per http request). Please leave another answer if you know of a better way, and I'll be more than happy to re accept a better solution.