>> It appears to be a Tomcat-specific issue :( > > This seems to be a problem with Shiro's OncePerRequestFilter and > Tomcat. The trouble is, Tomcat completes the execution of the filters > on the main request before then (apparently) forwarding to the error > handler. So before the error handler is invoked, the Shiro filter > clears the thread local variables, including the bound security > manager. The security manager is never bound again because the Shiro > filter extends OncePerRequestFilter which works out that this is still > the same request (it's a forward, you see). > > Is this incorrect behaviour in Tomcat? I have no idea. The servlet > specification does leave some holes, which means that it's not clear > what the correct behaviour should be. Note that Tomcat only appears to > perform a forward after completing the current request when it's > forwarding to an error handler.
It seems that the servlet specification makes no guarantees in this area. Tomcat's and Jetty's approaches are both valid. One thing that is guaranteed by the spec is that the servlet container will pass the original *unwrapped* request and response to the error handler, unless there are any filters specifically attached to the ERROR dispatcher. That means Shiro needs fixing. I propose that we modify OncePerRequestFilter such that the *.FILTERED request attribute is removed straight after the call to doFilterInternal(). Users and the Grails plugin can then configure the Shiro filter to trigger on the ERROR dispatcher if they want. Admittedly the filter would no longer be once-per-request, but the behaviour would be consistent between Tomcat and Jetty. Cheers, Peter
