Thanks for the advice -- it makes sense. I had been using a redirect
prior to encountering this issue but changed to rendering a response as
an attempt at a workaround. It seems that this probably compounded my
issue. I've switched back to redirect after signout.
Jeremy Haile wrote:
It's probably a best practice to issue an HTTP redirect after signout,
rather than sending back the HTML as part of the same request. I
think that would fix the issue (along with the code change)
You can do this in spring by 'return "redirect:/my/url"' or by calling
response.sendRedirect(..) I'm sure grails has an easy way to do that
too.
Jeremy
On Feb 9, 2009, at 5:11 PM, Brad Whitaker 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