Announcement Announcement Module
Collapse
No announcement yet.
Memory Leak: SecurityContextImpl held in ThreadLocal Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Memory Leak: SecurityContextImpl held in ThreadLocal

    I found a memory leak in my web-application, and I think it’s related to spring-security and/or spring-remoting.
    The web application is composed by a front-end tier (SpringMVC) that communicates with a service tier via spring-remoting. The service provides an authentication service (a spring authentication-provider facade) and a service facade. To access to the service facade we use an AuthenticationSimpleHttpInvokerRequestExecutor, although it does not require authentication for the moment.

    What I first spotted is that, after undeploying the application, a ServletContextImpl instance is kept in a ThreadLocal variable.
    Although I found the issue SEC-1578 in spring-security-3.0.3-RELEASE regarding a SecurityContextImpl instance that was removed with a ThreadLocal.set(null) instead of ThreadLocal.remove() . But even after upgrading to spring-security-3.0.5-RELEASE, the variable was there.

    I removed completely the spring-security configuration from my main application and the memory leak was gone. So I seeked the cause by restoring incrementally the different components in these steps:
    - setting only the maven dependency (no configuration at all)
    - setting up the simplest possible client side configuration (not using the remote service to authenticate)
    - using the SimpleHttpInvokerRequestExecutor in place of the AuthenticationSimpleHttpInvokerRequestExecutor (as the service does not actually enforce security). This gave me a memory leak due to a “Keep-Alive-Timer” thread not being released
    - finally I set up the AuthenticationSimpleHttpInvokerRequestExecutor and I got the SecurityContextImpl not being released

    Sure enough that I found the configuration to recreate the problem I started writing a minimal application to submit the case to the Spring Community, but unfortunately it only suffers for the “Keep-Alive” thread being held, no matter wich “HttpInvoker” I was using.

    I hope this is enough information to start look for the reason why the SecurityContextImpl is being held. Or you can give me a hint about how to fix it.

    The application I wrote is available at https://github.com/xan/SpringRemotingLeak

  • #2
    You are requesting the /secure-service?string=abc url, but the URL is not listed as an intercept-url.
    Code:
     <http auto-config="true">
            <intercept-url pattern="/public.jsp"
                           access="ROLE_USER,ROLE_ANONYMOUS"/>
            <intercept-url pattern="/private.jsp"
                           access="ROLE_USER"/>
        </http>

    This means the URL is not actually secure and that the SecurityContextPersistenceFilter will not clear the SecurityContext. Add a mapping for the /secure-service url and it should clear out the SecurityContext removing the leak within Spring Security. Let me know if this works. If you still have a leak post updates.

    Comment


    • #3
      If the springSecurityFilter is not configured in the web.xml, would you expect to be a memory leak?

      Comment


      • #4
        I actually need to retract my statement about needing to specify an intercept-url to get Spring Security to invoke the SecurityContextPersistenceFilter (which in turn should clear out the context). I was incorrect on that statement...either I was mixing up how older versions worked or I just plain messed up. I apologize.

        I tried your sample and hit a few issues. The API artifact id needed to be changed to AuthAPI so that it was found by the other projects. This was easy so I went ahead and did that. I then tried the tomcat:deploy step, but it gave me an error "Server not defined in settings.xml: tomcat-localhost". I am assuming that I need to configure my settings.xml, but I have not used the tomcat maven plugin for deploying before and do not have much free time at the moment. I did give it a quick try on my own instance of Tomcat and a quick analysis appears that the Keep Alive is the only things maintaining the reference (I did not see the SecurityContextImpl held in a ThreadLocal as you did). This could be due to the fact that I am a bit rushed, so I can take a look at it in more detail either later tonight or this weekend when I have a bit of free time. In the meantime I have a few things for you to do....

        Correct the maven artifact id. This will make sure we are both doing the exact same thing (perhaps the other artifact has a bug in it that I cannot see). Additionally, clean your local maven repository. This ensures that the correct jars are being used (this likely is why your project builds even though API is a different artifact than what is listed by the two wars).

        Ensure that the project works out of the box and provide exact information on how to reproduce. The steps are detailed, but things like settings.xml setup should likely be included. It would be bad if I configured mine a bit differently and that was why I couldn't reproduce (unlikely but a possibility). Also pushing a change for the artifactid would be nice.

        Upgrade Spring and Spring Security. Ensure that you validate all the transitive dependencies are also on the latest version. It sounded as though you may have tried this, but just double check after you have cleaned up your local maven repo and poms. It would be good if these changes were pushed to github too.

        Provide any additional setup instructions that you may have including JDK version, tomcat version, settings.xml configuration, etc as these may be needed in order for me to reproduce the problem.

        Cheers,

        Comment

        Working...
        X