JBoss Community

Re: LoginModule defined with cached=true, but called between web and ejb container

created by Patrick Garner in PicketBox Development - View the full discussion

Correct me if I'm wrong but it was a bug or at least bad programming practice on my part to invoke HttpServletRequest#logout and HttpSession#invalidate prior to LoginHistory#create.  I didn't notice the bug until I implemented Change Password workflow, which was when the FailedLoginException was thrown.  The problem was resolved by simply reversing the order e.g. invoking LoginHistory#create before logout.  However, it was troubling to learn that the EJB container was re-authenticating the user every time during the logout process after I explicitly invoked HttpServletRequest#logout and HttpSession.invalidate.

2- session.invalidate() is called, causing the security cache to purge the entry that corresponds to userA.

 

3- you call the LoginHistoryService EJB. The WEB layer will use the established security context to propagate the identity/password to the EJB container. As there is no cache entry for userA ...

 

So, if I understand you correctly, the security context remains established and userA (I'm assuming this means the principal) remains intact?  Wow.  Until now, I assumed that immediately upon invocation of logout and/or invalidate the security context was removed.  Perhaps it's not removed until the thread returns because of some requirement in the EJB spec, such as being able to pass principals across a chain of EJB calls?  Well... it was certainly confusing to receive a FailedLoginException when logging out  :)   and it was troubling that the application didn't receive an error except during logout under the unique circumstance when the user's password was changed during the session -- all because the EJB container was re-authenticating behind the scenes after logout was invoked.

When you call loginSuccess, you successfully invoke the EJB because the security cache is still active and the security context that was established in the web layer still reflect the correct username and password pair that exists in the DB. So when the invocation reaches the EJB container, the security cache is hit and the user is authenticated. Note that there's no way to escape authentication in the EJB container as all EJB calls are required to be authenticated by the EJB specification. Finally, you invalidate the session and return, so the existing security context is removed and when the client (browser) attempts to call a protected resource he should be redirected to the login page as the session has been terminated.

Just when I thought I was catching on, I'm confused again  ;)   I don't understand when you say that the EJB spec requires all EJB calls to be 'authenticated.'  It is my understanding that principals are authenticated -- not EJB calls -- and that EJB calls require access authorization -- not authentication.  If this is the case then referring back to my web application, since the security context (I'm assuming this means the principal) remains intact after invoking HttpServletRequest#logout and HttpSession#invalidate and until the thread returns there should be no reason to re-authenticate the principal before the thread returns.  In other words, if the principal is authenticated at login and logout is invoked but does not remove the security context, and during logout (e.g. before the thread returns) a secure EJB method is invoked, the EJB container should perform access authorization, checking that the user has the proper role, and not authentication, and, hence, the FailedLoginException should never be thrown after invoking logout before the thread returns.

Reply to this message by going to Community

Start a new discussion in PicketBox Development at Community