Re: [securityfilter-user] SecurityFilter doing authentication upon logout?
Brought to you by:
chris_schultz,
maxcooper
From: Christopher S. <ch...@ch...> - 2009-05-07 15:41:34
|
Matt, On 5/5/2009 6:51 PM, Matthew Hixson wrote: > We have a method that updates the database with the last time that a > user logs in. I put a Thread.dumpStack() call in my method, > updateLastLogin(). The problem I have is that upon logout execution > ends up passing through this method again which, of course, has the > result of logging to the database the time that the user logged out. That's definitely odd. What version of sf are you using? > While logging in the stack trace looks like this. > > java.lang.Exception: Stack trace > at java.lang.Thread.dumpStack(Thread.java:1176) > at mycompany.SpecialAuthenticator.updateLastLogin(SpecialAuthenticator.java:36) > at com.mycompany.authentication.SARealm.authenticate(SARealm.java:140) > at org.securityfilter.realm.catalina.CatalinaRealmAdapter.authenticate(CatalinaRealmAdapter.java:95) > at org.securityfilter.authenticator.FormAuthenticator.processLogin(FormAuthenticator.java:297) > at org.securityfilter.filter.SecurityFilter.doFilter(SecurityFilter.java:144) > at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) > [...] [snip] > While logging out it produces this: > > java.lang.Exception: Stack trace > at java.lang.Thread.dumpStack(Thread.java:1176) > at mycompany.SpecialAuthenticator.updateLastLogin(SpecialAuthenticator.java:36) > at com.mycompany.authentication.SARealm.authenticate(SARealm.java:140) > at org.securityfilter.realm.catalina.CatalinaRealmAdapter.authenticate(CatalinaRealmAdapter.java:95) > at org.securityfilter.authenticator.FormAuthenticator.processLogin(FormAuthenticator.java:284) > at org.securityfilter.filter.SecurityFilter.doFilter(SecurityFilter.java:144) > at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) > [...] Hmm... the line numbers are different in the call to CatalinaRealmAdapter.authenticate from FormAuthenticator.processLogin. Have you been hacking the sf code yourself, or is everything as you got it from the original dist package? > So, why does > org.securityfilter.authenticator.FormAuthenticator.processLogin() end > up getting called when the user is logging out? My relevant part of > securityfilter-config.xml looks like: > > <login-config> > <auth-method>FORM</auth-method> > <form-login-config> > <form-login-page>/login.jsp</form-login-page> > <form-error-page>/login.jsp?err=1</form-error-page> > <form-default-page>/members/index.jsp</form-default-page> > <form-logout-page>/logout.jsp</form-logout-page> What about your <security-constraint> sections? > <!-- remember-me config --> Does disabling <remember-me> have any effect on this behavior? > I put some debug code into my /logout.jsp to see if that were somehow > triggering something, but the stack trace happens before execution > even enters logout.jsp. Right: the filter executes before any servlet (or JSP) code does. > Any thoughts on how I can prevent my Realm's authenticate() method > being called upon logout? And am I incorrect in assuming that > authenticate() should only be called upon initial login? Generally, yes. Don't be fooled by the call to processLogin: this method is called to /determine/ if the request is for a login and take appropriate actions. The FormAuthenticator first checks to see if you are using a persistent log manager (you are) and uses the remembered credentials for authentication (that's on line 284, as in your second stack trace). Your second case appears to match this. Whether you are using a persistent manager or not, FormAuthenticator continues with the standard login mechanism (which appears to be shown in your second stack trace). The request is checked (endsWith) against the loginSubmitPattern which defaults to "/j_security_check". What does your <filter> configuration look like for sf? Are you passing-in any <filter-init-param>s? Can you post the URLs you are using that end up with stack traces #1 and #2? Is there any forwarding or redirecting going on? I suspect that you have "persistent logins" enabled and so when you hit logout.jsp, you are being re-logged-in using the persistent manager. Although the persistent manager is supposed to forget your login /before/ trying to log you in again. I think there might be a bug in the persistent login manager, because the rememberingLogin() method is this: if (getCookieValue(request.getCookies(), COOKIE_REMEMBERME, "false").equals("true")) { return true; } else { return false; } During a logout request, any persistent login cookies will be sent along with the request as usual. The logout will trigger the persistent manager to forget your login. The subsequent login check uses the cookie /still in the request/ to log you back in. Duh. No offense to the original authors of this code, but I somewhat recently inherited this project, and I've never used the PersistentManager myself. It seems like the PersistentManager has a relatively big bug, here, in that it is not possible to log out. :) Are you willing to recompile sf? If so, try making the following changes: 1. In DefaultPersistentManager.forgetLogin, add this code: request.setAttribute("persistentLoginManager.logout", Boolean.TRUE); 2. Change DefaultPersistentManager.rememberingLogin to this: return getCookieValue(request.getCookies(), COOKIE_REMEMBERME, "false").equals("true")) && !Boolean.TRUE.equals(request.getAttribute("persistentManager.logout")) ; See if that fixes your logout problem. -chris |