Hi Brad - if after you sign out, your browser sends another request, that
should be ok - the first response would set a 'deletion cookie', (setting
the max age to 0), telling the browser to remove it, and any subsequent
requests shouldn't have the cookie at all (not until a new loging was
created at least).

That is, if this occurred:

Logout request ---> jsecurity filter --> your webapp -->
SecurityUtils.getSubject().logout();
<---- response
Css request --> jsecurity filter --> your webapp
<---- response

The CSS request should (if working correctly) never send back a rememberMe
cookie.

If you do see the cookie though, even after logout, there is one scenario
that I can think of that would cause this:

Because cookies are part of the HTTP header, they must be set _before_ the
response has started rendering (response output stream is written to).  That
means you must ensure the logout() call is made before any HTML is sent to
the output stream.  This allows JSecurity to set its 'deletion cookie'
(maxage = 0) to the response at logout() time.

If you call logout() in a controller before any view is rendered, or at the
top of a JSP file before the DOCTYPE declaration, you would be ok.  If you
don't do these things, the 'deletion cookie' can't be sent to the browser,
and subsequent requests would have the cookie.

This is why people often perform a redirect immediately after calling
logout() - to ensure HTML rendering can never happen.  You don't have to do
this of course - its just a quick way to ensure the problem can't occur.

Best,

Les

On Mon, Feb 9, 2009 at 5:11 PM, Brad Whitaker <[email protected]> wrote:

> I've pinpointed the cause of my problem and have been able to fix (or at
> least work around it).
>
> After receiving a signout request my server sends back HTML with a
> reference to a CSS stylesheet. (In my case the reference is to an IE
> specific CSS file, and the reference was bad so it wasn't being cached by
> the client). The request for the CSS file from the clien apparently
> contained the rememberMe cookie, so the value of the cookie was again
> associated with the client.
>
> I don't know enough details about the HTTP specification to know if this
> means there is a bug with IE, JSecurity, or whether my case was so unusual
> that it just isn't worth worrying about.
>
>
> Thanks,
>
> Brad
>
> Brad Whitaker wrote:
>
>> I'm still blocked by this issue and would appreciate any suggestions. The
>> problem is that SpringJSecurityFilter is being executed a second time during
>> my signOut request. I have no idea why this is happening. (The parent class
>> OncePerRequestFilter cannot really fulfill the mission that its name
>> implies. The request.setAttribute() value that is set during the first
>> execution is not present during the second execution.)
>> response.isCommitted() is also false during the second execution so the
>> strategy from JSEC-58 is of no use in this case.
>>
>> I don't understand enough about the servlet filter mechanism to understand
>> why the filter is being executed twice, or how to stop it. I'm also not
>> clear if this is a Grails related problem or not.
>>
>> I have determined that my problem only occurs with IE -- it does not
>> happen with other browsers such as Firefox.
>>
>> Thanks,
>>
>> Brad
>>
>> Brad Whitaker wrote:
>>
>>> I got some help from the Grails list that enabled me to set the
>>> init-param on DispatcherServlet. (Actually, it's a subclass in Grails called
>>> GrailsDispatcherServlet). Unfortunately neither this change nor my patch has
>>> solved my problem.
>>>
>>> I've been looking at my logs and it seems that at the very end of request
>>> processing (i.e. after a Grails filter 'afterView' method has fired) that
>>> Grails is unbinding the request from a thread, and then binding the request
>>> to a new thread. Something is then calling JSecurity code (including
>>> WebRememberMeManager). At this point the "logged out" flag is no longer
>>> associated with the request, and the cookie is read again.
>>>
>>> Here's some relevant log output:
>>>
>>> 02/07 15:05:06 DEBUG
>>> org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet  -
>>> Successfully completed request
>>> 02/07 15:05:06 DEBUG
>>> org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter  - Matched
>>> URI [/auth/signOut] to URL mapping [/(*)/(*)?/(*)?], forwarding to
>>> [/grails/auth/signOut.dispatch] with response [class
>>> org.codehaus.groovy.grails.web.sitemesh.GrailsPageResponseWrapper]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Removed value of
>>> type [org.jsecurity.web.DefaultWebSecurityManager] for key
>>> [org.jsecurity.util.ThreadContext_SECURITY_MANAGER_KEY]from thread
>>> [TP-Processor6]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Removed value of
>>> type [org.apache.catalina.connector.ResponseFacade] for key
>>> [javax.servlet.ServletResponse_JSECURITY_THREAD_CONTEXT_KEY]from thread
>>> [TP-Processor6]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Removed value of
>>> type [org.jsecurity.web.servlet.JSecurityHttpServletRequest] for key
>>> [javax.servlet.ServletRequest_JSECURITY_THREAD_CONTEXT_KEY]from thread
>>> [TP-Processor6]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Removed value of
>>> type [java.net.Inet4Address] for key
>>> [org.jsecurity.util.ThreadContext_INET_ADDRESS_KEY]from thread
>>> [TP-Processor6]
>>> 02/07 15:05:06 DEBUG
>>> org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter  - Cleared
>>> Grails thread-bound request context:
>>> org.apache.catalina.connector.requestfac...@9ada28
>>> 02/07 15:05:06 DEBUG
>>> org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter  - Bound
>>> Grails request context to thread:
>>> org.apache.catalina.connector.requestfac...@687f95
>>> 02/07 15:05:06 TRACE org.jsecurity.web.servlet.OncePerRequestFilter  -
>>> Filter not yet executed.  Executing now.
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Bound value of
>>> type [java.net.Inet4Address] for key
>>> [org.jsecurity.util.ThreadContext_INET_ADDRESS_KEY] to thread
>>> [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Bound value of
>>> type [org.jsecurity.web.servlet.JSecurityHttpServletRequest] for key
>>> [javax.servlet.ServletRequest_JSECURITY_THREAD_CONTEXT_KEY] to thread
>>> [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Bound value of
>>> type [org.apache.catalina.connector.ResponseFacade] for key
>>> [javax.servlet.ServletResponse_JSECURITY_THREAD_CONTEXT_KEY] to thread
>>> [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Bound value of
>>> type [org.jsecurity.web.DefaultWebSecurityManager] for key
>>> [org.jsecurity.util.ThreadContext_SECURITY_MANAGER_KEY] to thread
>>> [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - get() - in
>>> thread [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - get() - in
>>> thread [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - get() - in
>>> thread [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.util.ThreadContext  - Retrieved value
>>> of type [org.jsecurity.web.servlet.JSecurityHttpServletRequest] for key
>>> [javax.servlet.ServletRequest_JSECURITY_THREAD_CONTEXT_KEY] bound to thread
>>> [TP-Processor8]
>>> 02/07 15:05:06 TRACE org.jsecurity.web.WebRememberMeManager  -
>>> getRememberedPrincipals: not found: FORGET_IDENTITY_ATTRIBUTE_NAME
>>>
>>>
>>> Brad Whitaker wrote:
>>>
>>>> I did notice this part of his response but it is not obvious to me how I
>>>> make this modification to my Grails app.
>>>>
>>>> Les Hazlewood wrote:
>>>>
>>>>> Oops - you might have missed Jeremy's response:
>>>>>
>>>>> "In my case, Spring was calling request.getUserName(), which under the
>>>>> hood
>>>>> called JSecurity's getSubject().  To stop this from happening I had to
>>>>> set
>>>>> the publishEvents init-param to false on my Spring DispatcherServlet,
>>>>> which
>>>>> stopped Spring from calling the getUserName() function."
>>>>>
>>>>> Try that.  We'll get on the issue and fix it.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Les
>>>>>
>>>>> On Fri, Feb 6, 2009 at 8:49 PM, Brad Whitaker <[email protected]>
>>>>> wrote:
>>>>>
>>>>>
>>>>>
>>>>>> Thanks for the response. This is a blocker for me. I disabled all of
>>>>>> my
>>>>>> explicit getSubject() calls but perhaps something else is still making
>>>>>> the
>>>>>> invocation. Would any Spring application be making this call? (In
>>>>>> other
>>>>>> words, would any Grails app being making the same call that you saw?)
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Brad
>>>>>>
>>>>>>
>>>>>>
>>>>>> Jeremy Haile wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>> I just ran into this same problem.  I think it is a JSecurity bug.
>>>>>>>  The
>>>>>>> problem is that if any methods invoke getSubject() after logout() is
>>>>>>> called,
>>>>>>> but during the same request, a new subject will be created.  But
>>>>>>> since the
>>>>>>> remember me cookie is still present, the subject gets created in the
>>>>>>> new
>>>>>>> Session with the remembered principals.
>>>>>>>
>>>>>>> The problem doesn't occur if getSubject() isn't called after
>>>>>>> logout().  In
>>>>>>> my case, Spring was calling request.getUserName(), which under the
>>>>>>> hood
>>>>>>> called JSecurity's getSubject().  To stop this from happening I had
>>>>>>> to set
>>>>>>> the publishEvents init-param to false on my Spring DispatcherServlet,
>>>>>>> which
>>>>>>> stopped Spring from calling the getUserName() function.
>>>>>>>
>>>>>>> Still - this shouldn't be necessary and I think the onus is on
>>>>>>> JSecurity
>>>>>>> to figure out how to make this not happen.  Perhaps we can set a
>>>>>>> request
>>>>>>> attribute that causes the remember me cookie to not be honored for
>>>>>>> the
>>>>>>> remainder of that request.  Any other ideas for how to work around
>>>>>>> this
>>>>>>> problem?
>>>>>>>
>>>>>>> I filed a bug report here:
>>>>>>> https://issues.apache.org/jira/browse/JSEC-57
>>>>>>>
>>>>>>> Jeremy
>>>>>>>
>>>>>>>
>>>>>>> On Feb 6, 2009, at 6:26 PM, Brad Whitaker wrote:
>>>>>>>
>>>>>>>  I'm having a problem that I don't fully understand. After I invoke
>>>>>>>
>>>>>>>
>>>>>>>> logout() the subject.principal becomes null as expected, but upon
>>>>>>>> redirect
>>>>>>>> the subject.principal is no longer null -- the user is remembered
>>>>>>>> again. The
>>>>>>>> log messages from JSecurity indicate a rememberMe cookie has been
>>>>>>>> found when
>>>>>>>> I think it probably shouldn't be found.
>>>>>>>>
>>>>>>>> The issue does not occur in my devel environment (Grails, HSQLDB)
>>>>>>>> but
>>>>>>>> only in production (Tomcat, MySql, war deployed as ROOT). My signout
>>>>>>>> code
>>>>>>>> does this:
>>>>>>>>
>>>>>>>>         log.info "signout: enter:
>>>>>>>>  getPrincipal=${SecurityUtils?.getSubject()?.getPrincipal()}"
>>>>>>>>         SecurityUtils.subject?.logout()
>>>>>>>>         log.info "signout: after logout:
>>>>>>>>  getPrincipal=${SecurityUtils?.getSubject()?.getPrincipal()}"
>>>>>>>>         redirect(controller: 'home')
>>>>>>>>
>>>>>>>> My log shows this. (You'll notice that I have several 'before' and
>>>>>>>> 'after' filters)
>>>>>>>>
>>>>>>>>  02/06 15:10:57 INFO  grails.app.controller.AuthController  -
>>>>>>>>  signout: enter:  [email protected]
>>>>>>>>  02/06 15:10:57 DEBUG org.jsecurity.web.attr.CookieAttribute  - No
>>>>>>>>  value found in request Cookies under cookie name [rememberMe]
>>>>>>>>  02/06 15:10:57 INFO  grails.app.controller.AuthController  -
>>>>>>>>  signout: after logout:  getPrincipal=null
>>>>>>>>  02/06 15:10:57 INFO  grails.app.filters.SslFilters  - DebugFilter:
>>>>>>>>  after: controller=auth action=signOut params=["action":"signOut",
>>>>>>>>  "controller":"auth"] principal=null
>>>>>>>>  02/06 15:10:57 DEBUG org.jsecurity.web.attr.CookieAttribute  -
>>>>>>>> Found
>>>>>>>>  string value
>>>>>>>>  
>>>>>>>> [clJgEjFZVuRRN5lCpInkOsawSaKK4hLwegZK/QgR1Thk380v5wL9pA1NZo7QHr7erlnry1vt2AqIyM8Fj2HBCsl1lierxE9EJ1typI2GpgMeG+HmceNdrlN6KGh4AmjLG3zCUPo8E+QzGVs/EO3PIAGyYYtuYbW++oJDr5xfY9DwK4Omq5GijZSSmdpOHiYelPMa1XLwT0D/kNCUm6EVfG6TKwxViNtGdyzknY7abNU7ucw2UWfjFe24hH0SL0hZMXjPQYtMnPl5J5qfjU4EXX1a/Ijn0IKUEk5BmY+ipc6irMI/Rrmumr7XSSncSHq2cpyNbwJBykFX5s/ydB64hbMenS+LhbUvnQBNt8Xkjyc+IrzntDuVGH4IGfnRIAOwDkU6EZPQ4v36wbd8IB3kUFW1/1z6ZvS4jsIgMA3TS2xMjhGB8FWnIG9RSOrT+nlejddqoRsTWWmEAWUuaOV3tZLci69POQ5k]
>>>>>>>>
>>>>>>>>
>>>>>>>>  from HttpServletRequest Cookie [rememberMe]
>>>>>>>>  02/06 15:10:57 INFO  grails.app.filters.SslFilters  - DebugFilter:
>>>>>>>>  before: controller=home action=null params=["controller":"home"]
>>>>>>>>  [email protected]
>>>>>>>>  02/06 15:10:57 INFO  grails.app.filters.SslFilters  - DebugFilter:
>>>>>>>>  after: controller=home action=index params=["controller":"home"]
>>>>>>>>  [email protected]
>>>>>>>>
>>>>>>>> Is this a bug in JSecurity or am I doing something wrong? Is there a
>>>>>>>> work
>>>>>>>> around for this?
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>>
>>>>>>>> Brad
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>

Reply via email to