Announcement Announcement Module
No announcement yet.
HttpSessionContextIntegrationFilter thread racing?? Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • HttpSessionContextIntegrationFilter thread racing??


    I have a quite big application on weblogic 9.2. Tapestry 3.0.3 ,Acegi 1.0.3 , Spring 1.2.8 is used.
    I have a weird problem during logging into application. If i provide user, password
    and i am successfully authenticated i am redirected to login page again. It only happens time to time.
    After 1 day of hard debugging i think i found how this thing happens:

    I am using following acegi filters:
    concurrentSessionFilter (org.acegisecurity.concurrent.ConcurrentSessionFil ter), httpSessionContextIntegrationFilter(org.acegisecur ity.context.HttpSessionContextIntegrationFilter), authenticationProcessingFilter(derived form AuthenticationProcessingFilter), exceptionTranslationFilter, checkAccountExpirationFilter, filterInvocationInterceptor

    The most important part is: after user provided its name and password httpSessionContextIntegrationFilter comes into play. There is no securityContext in session so a new, dumb context is created (method generateNewContext()), then processing is moved to authenticationProcessingFilter. This filter is derived from AuthenticationProcessingFilter to override obtainusername and obtain password methods. If authorization is successful successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication) is fired which redirects to main page of application.
    Sometimes new request from user (because of redirection )comes faster than the second part of httpSessionContextIntegrationFilter - (the code after chain.doFilter(request, response)) associated with a previous request is run.
    For a new request (to main page of application) the authentication object form session is null ! and filterInvocationInterceptor reditrects me to a login page form. I still need to log in again even that i am currently logged - i can manipulate URL in a browser address bar to get access to secured parts of application.

    I hope that it is clear what i wrote above. Can anyone help me??. Do i need to provide some kind of serialization filter to make sure that request are handled in a proper order ???

  • #2
    I don't think that this is a problem within acegi. The point is, when a second request arrives while the first (doing authentication) has not finished, then the second request is redirected to the login page as well. When you then are able to access secured pages that is, because you have the same identity and authentication has finished meanwhile.

    The question is, why are the requests issued in such a short timeinterval? As I understand Tapestry is event based, so maybe the event processing does cause this. I'm no expert in Tapestry, so that is just a guess.



    • #3
      You are right. Anyway i am testing my application from localhost.
      Beside this, don't you think it can be quite dangerous to assume that second request (because of dispatching) will be processed later than finalizing part of httpsessioncontextintegration filter. I may have very slow server and test it from localhost...


      • #4
        Originally posted by miluch View Post
        Beside this, don't you think it can be quite dangerous to assume that second request (because of dispatching) will be processed later than finalizing part of httpsessioncontextintegration filter.
        Actually I see it less dangerous to assume a request to be unauthenticated when it might be authenticated as the other way around.

        Originally posted by miluch View Post
        I may have very slow server and test it from localhost...
        I would dig a bit into the dispatching. I am wondering what causes these races in the first place.



        • #5
          After some more debugging I found a solution. A little bit a hack but seems to work.
          If anyone is interested please keep reading.

          After user press submit button on login form, request goes to /login.
          Let's call this request r1. For r1 all the filters in a chain are applied - obviously the "before part" of filters -before chain.doFilter command. Than a tapestry page is processed that makes a little processing and then dispatches the request (dispatcher.forward) to /j_acegi_security_check. A new internal server request, let's call it r1a, is made. For r1A the filters are applied again, but httpsessioncontextintegrationfilter does nothing except for chain.doFilter.
          It is because the filter has been already applied to the request - in my case, to request r1.
          R1a is finally processed by AuthenticationProcessingFilter and if user provided valid data new redirect is made to main page of application. Let's call this request r2.
          Next, the "after part" of filters - after chain.doFilter command, of filters associated with request r1a are processed. Please remember that there is no "after part" of httpsessioncontextintegrationfilter for r1a.
          After r1a is completed, "after part" of filters for request r1 are processed -the most important, "after part" of httpsessioncontextintegrationfilter stores securitycontext in a session. My problem was that sometimes request r2( new request from browser) was processed before "after part" of httpsessioncontextintegrationfilter associated with r1 was run. In the result, login form was presented again, but user had already been authenticated.

          My 'hack' solution was to apply full processing of httpsessioncontextintegrationfilter for r1a, so just before dispatching to /j_acegi_security_check i remove "__acegi_session_integration_filter_applied"
          request attribute. I do this because i want to store securitycontext in a session a little bit earlier -for request r1a not only for r1.
          I hope my explanation can help someone.
          Last edited by miluch; Mar 7th, 2007, 04:13 AM.


          • #6
            I don't think this will occur. the redirect will happen after all filters are processed and complete. for example, you have 2 filters.
            Filter1: System.out.println("before 11111111111111111");
            chain.doFilter(req, res);
            System.out.println("after 11111111111111111");
            try {
            } catch (InterruptedException e) {
            // TODO Auto-generated catch block


            public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            System.out.println("before 2222222222222");
            chain.doFilter(req, res);
            System.out.println("after 2222222222222");
            HttpServletResponse response = (HttpServletResponse) res;

            the log will be: before 1111, before 222, after 2222, after111, the it waits 10 seconds, finally it redirects to Search.html