Create session errors on login after session timeout

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Create session errors on login after session timeout

martin

 

I’m seeing an error on login each time the session times out in my web application, followed by the user logging out and logging in. The webapp provides a logout link, which does not have any logic to disable/enable the link based on whether the session has timed out or not – the user can click the logout link but subject.logout() will not actually be called (see below). In normal operation, logging in, out, and back in again works fine. If the user logs in and then waits for the session to time-out, then hits the logout link the following gets executed:

 

if (subject.isAuthenticated()) {

subject.logout();

}

 

The subject.logout() is not actually called as the session has expired so isAuthenticated() returns false. Following this the user lands on the login page again. Next request to login fails with this error:

 

18:33:18,328 ERROR [Identity] (http--0.0.0.0-8080-5) () Login failed: java.lang.IllegalArgumentException: HttpSession constructor argument cannot be null.

        at org.apache.shiro.web.session.HttpServletSession.<init>(HttpServletSession.java:51) [shiro-web-1.2.0-20120120.051708-65.jar:]

        at org.apache.shiro.web.session.mgt.ServletContainerSessionManager.createSession(ServletContainerSessionManager.java:119) [shiro-web-1.2.0-201

20120.051708-65.jar:]

        at org.apache.shiro.web.session.mgt.ServletContainerSessionManager.createSession(ServletContainerSessionManager.java:115) [shiro-web-1.2.0-201

20120.051708-65.jar:]

        at org.apache.shiro.web.session.mgt.ServletContainerSessionManager.start(ServletContainerSessionManager.java:64) [shiro-web-1.2.0-20120120.051

708-65.jar:]

        at org.apache.shiro.mgt.SessionsSecurityManager.start(SessionsSecurityManager.java:121) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:336) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:314) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.mgt.DefaultSubjectDAO.mergePrincipals(DefaultSubjectDAO.java:182) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.mgt.DefaultSubjectDAO.saveToSession(DefaultSubjectDAO.java:163) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.mgt.DefaultSubjectDAO.save(DefaultSubjectDAO.java:144) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.mgt.DefaultSecurityManager.save(DefaultSecurityManager.java:383) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:350) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:183) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:283) [shiro-core-1.2.0-20120120.051646-69.jar:]

        at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:257) [shiro-core-1.2.0-20120120.051646-69.jar:]

 

 

Normal logouts following by logins work fine if the session does not time out, but the error is thrown on each login attempt following a session timeout and logout.

 

I thought the most likely cause would be a mistake where subject.logout() is called in the same request/response as making a subject.login() call – but have confirmed this is not the case. Suspect this may be session management related, but not clear what might be causing this - any ideas?

 

Thanks,

 

Martin

 

 

Reply | Threaded
Open this post in threaded view
|

Re: Create session errors on login after session timeout

Les Hazlewood
Administrator
Hi Martin,

This is happening, because of whatever reason, the servlet container
appears to be returning a null value from
httpServletRequest.getSession(); an HttpSession is required when
instantiating an HttpServletSession (the Shiro Session implementation
that delegates to the HttpSession API).

See https://svn.apache.org/repos/asf/shiro/tags/shiro-root-1.2.0/web/src/main/java/org/apache/shiro/web/session/mgt/ServletContainerSessionManager.java

in the createSession(SessionContext);

Because we didn't see a NullPointerException, we know the
HttpServletRequest is not null.  Therefore, this line is returning
null:

HttpSession session = request.getSession();

How is it possible that the servlet container is returning a null
Session?  One potential reason is it seems as if page content begins
rendering before Shiro tries to invoke
httpServletRequest.getSession().  If so, this means that the servlet
container cannot satisfy creating a session for that request (once
content is rendered, HTTP headers - ala session id cookie - cannot be
sent, and therefore a session can't be created for that request).

Is this possible this is happening in your app?  If not, I have no
idea why the servlet container HttpServletRequest would not honor the
getSession() call.  If you could put a break point in a debugger at
that point and let us know what you find, I'd love to know what you
see.

On a side note, if someone clicks 'logout', I would _always_ call
subject.logout(), even if they're not yet authenticated - it allows
session cleanup, events to be triggered (and reacted to by your
software), and satisfies a contract with an end-user (i.e. "i'm not
using this application anymore, you should do whatever you do to
ensure everything about me is cleaned up").

HTH,

Les

On Mon, Jan 23, 2012 at 11:20 AM, Martin Dixon <[hidden email]> wrote:

>
>
> I’m seeing an error on login each time the session times out in my web
> application, followed by the user logging out and logging in. The webapp
> provides a logout link, which does not have any logic to disable/enable the
> link based on whether the session has timed out or not – the user can click
> the logout link but subject.logout() will not actually be called (see
> below). In normal operation, logging in, out, and back in again works fine.
> If the user logs in and then waits for the session to time-out, then hits
> the logout link the following gets executed:
>
>
>
> if (subject.isAuthenticated()) {
>
> subject.logout();
>
> }
>
>
>
> The subject.logout() is not actually called as the session has expired so
> isAuthenticated() returns false. Following this the user lands on the login
> page again. Next request to login fails with this error:
>
>
>
> 18:33:18,328 ERROR [Identity] (http--0.0.0.0-8080-5) () Login failed:
> java.lang.IllegalArgumentException: HttpSession constructor argument cannot
> be null.
>
>         at
> org.apache.shiro.web.session.HttpServletSession.<init>(HttpServletSession.java:51)
> [shiro-web-1.2.0-20120120.051708-65.jar:]
>
>         at
> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.createSession(ServletContainerSessionManager.java:119)
> [shiro-web-1.2.0-201
>
> 20120.051708-65.jar:]
>
>         at
> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.createSession(ServletContainerSessionManager.java:115)
> [shiro-web-1.2.0-201
>
> 20120.051708-65.jar:]
>
>         at
> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.start(ServletContainerSessionManager.java:64)
> [shiro-web-1.2.0-20120120.051
>
> 708-65.jar:]
>
>         at
> org.apache.shiro.mgt.SessionsSecurityManager.start(SessionsSecurityManager.java:121)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:336)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:314)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSubjectDAO.mergePrincipals(DefaultSubjectDAO.java:182)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSubjectDAO.saveToSession(DefaultSubjectDAO.java:163)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSubjectDAO.save(DefaultSubjectDAO.java:144)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.save(DefaultSecurityManager.java:383)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:350)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:183)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:283)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:257)
> [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>
>
>
>
> Normal logouts following by logins work fine if the session does not time
> out, but the error is thrown on each login attempt following a session
> timeout and logout.
>
>
>
> I thought the most likely cause would be a mistake where subject.logout() is
> called in the same request/response as making a subject.login() call – but
> have confirmed this is not the case. Suspect this may be session management
> related, but not clear what might be causing this - any ideas?
>
>
>
> Thanks,
>
>
>
> Martin
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

RE: Create session errors on login after session timeout

martin

Many thanks Les. As you said it seems content is getting rendered somewhere before the getSession() calls - haven't got to the bottom of it yet, but adding a page refresh after session time-out page redirection has avoided the problem until I can investigate further.

Martin

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Les Hazlewood
Sent: 23 January 2012 21:12
To: [hidden email]
Subject: Re: Create session errors on login after session timeout

Hi Martin,

This is happening, because of whatever reason, the servlet container appears to be returning a null value from httpServletRequest.getSession(); an HttpSession is required when instantiating an HttpServletSession (the Shiro Session implementation that delegates to the HttpSession API).

See https://svn.apache.org/repos/asf/shiro/tags/shiro-root-1.2.0/web/src/main/java/org/apache/shiro/web/session/mgt/ServletContainerSessionManager.java

in the createSession(SessionContext);

Because we didn't see a NullPointerException, we know the HttpServletRequest is not null.  Therefore, this line is returning
null:

HttpSession session = request.getSession();

How is it possible that the servlet container is returning a null Session?  One potential reason is it seems as if page content begins rendering before Shiro tries to invoke httpServletRequest.getSession().  If so, this means that the servlet container cannot satisfy creating a session for that request (once content is rendered, HTTP headers - ala session id cookie - cannot be sent, and therefore a session can't be created for that request).

Is this possible this is happening in your app?  If not, I have no idea why the servlet container HttpServletRequest would not honor the
getSession() call.  If you could put a break point in a debugger at that point and let us know what you find, I'd love to know what you see.

On a side note, if someone clicks 'logout', I would _always_ call subject.logout(), even if they're not yet authenticated - it allows session cleanup, events to be triggered (and reacted to by your software), and satisfies a contract with an end-user (i.e. "i'm not using this application anymore, you should do whatever you do to ensure everything about me is cleaned up").

HTH,

Les

On Mon, Jan 23, 2012 at 11:20 AM, Martin Dixon <[hidden email]> wrote:

>
>
> I’m seeing an error on login each time the session times out in my web
> application, followed by the user logging out and logging in. The
> webapp provides a logout link, which does not have any logic to
> disable/enable the link based on whether the session has timed out or
> not – the user can click the logout link but subject.logout() will not
> actually be called (see below). In normal operation, logging in, out, and back in again works fine.
> If the user logs in and then waits for the session to time-out, then
> hits the logout link the following gets executed:
>
>
>
> if (subject.isAuthenticated()) {
>
> subject.logout();
>
> }
>
>
>
> The subject.logout() is not actually called as the session has expired
> so
> isAuthenticated() returns false. Following this the user lands on the
> login page again. Next request to login fails with this error:
>
>
>
> 18:33:18,328 ERROR [Identity] (http--0.0.0.0-8080-5) () Login failed:
> java.lang.IllegalArgumentException: HttpSession constructor argument
> cannot be null.
>
>         at
> org.apache.shiro.web.session.HttpServletSession.<init>(HttpServletSess
> ion.java:51) [shiro-web-1.2.0-20120120.051708-65.jar:]
>
>         at
> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.create
> Session(ServletContainerSessionManager.java:119)
> [shiro-web-1.2.0-201
>
> 20120.051708-65.jar:]
>
>         at
> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.create
> Session(ServletContainerSessionManager.java:115)
> [shiro-web-1.2.0-201
>
> 20120.051708-65.jar:]
>
>         at
> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.start(
> ServletContainerSessionManager.java:64)
> [shiro-web-1.2.0-20120120.051
>
> 708-65.jar:]
>
>         at
> org.apache.shiro.mgt.SessionsSecurityManager.start(SessionsSecurityMan
> ager.java:121) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.subject.support.DelegatingSubject.getSession(Delegati
> ngSubject.java:336) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.subject.support.DelegatingSubject.getSession(Delegati
> ngSubject.java:314) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSubjectDAO.mergePrincipals(DefaultSubjectD
> AO.java:182) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSubjectDAO.saveToSession(DefaultSubjectDAO
> .java:163) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSubjectDAO.save(DefaultSubjectDAO.java:144
> ) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.save(DefaultSecurityManage
> r.java:383) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecur
> ityManager.java:350) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecur
> ityManager.java:183) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManag
> er.java:283) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>         at
> org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSub
> ject.java:257) [shiro-core-1.2.0-20120120.051646-69.jar:]
>
>
>
>
>
> Normal logouts following by logins work fine if the session does not
> time out, but the error is thrown on each login attempt following a
> session timeout and logout.
>
>
>
> I thought the most likely cause would be a mistake where
> subject.logout() is called in the same request/response as making a
> subject.login() call – but have confirmed this is not the case.
> Suspect this may be session management related, but not clear what might be causing this - any ideas?
>
>
>
> Thanks,
>
>
>
> Martin
>
>
>
>