5 Replies Latest reply on Sep 3, 2006 4:00 PM by Brian Stansberry

    Weird apache behaviour in load-balancing, and form-based aut

    Alberto Rodriguez Newbie

      We have a project that we want to add fail-over and load-balancing features. Our app also uses SSO and session replication in a cluster environment using the great jboss-tomcat tamdem.

      The problem arises when apache is configured to load balance, in a round robin manner, between up to four jboss instances (mod_jk). Our app uses form-based authentication.

      Imagine we have a system configured with four jboss instances with session replication and single sign-on working. When we add apache to the scenario, everything begins to go wrong. Apache has a Round Robin schema and the first unauthenticated request goes to the first worker wich redirects the request to login.jsp, when the user provides it's credentials, the subsecuent request ( j_security_check as it's form-based authentication) goes to the second worker wich has no kwnoledge of a previous unauthenticated request and issues an "HTTP 400 invalid direct invocation of form" error as servlet's specification states.

      Is there any way of circumventing this problem?, other solution than substituting the authentication mechanism?

      Is there any way of configuring apache to be aware of the previous unauthenticated request and instruct it to direct the j_security_check request to the previous ( the one who redirected to login.jsp ) instance.

      Grets,

        • 1. Re: Weird apache behaviour in load-balancing, and form-based
          Hany Mesha Novice

          It looks like you don't have sticky session enabled on the cluster. Please check this wiki page on how to correctly configure apache with mod_jk and JBoss Clustering http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingMod_jk1.2WithJBoss

          • 2. Re: Weird apache behaviour in load-balancing, and form-based
            Alberto Rodriguez Newbie

            No, I don't, if I configure sticky sessions I would get all my user session live in only one node of the cluster and I would only get more fail-over capabilities but not real load balancing where any request could be answered by any node on the cluster (for instance the one with more free cpu cycles).

            I'm afraid by your answer that there are no solutions for this problem, as it is hard to solve being a particular case of use, isn't it?

            • 3. Re: Weird apache behaviour in load-balancing, and form-based
              Brian Stansberry Master

              Why would all the sessions live on one server? Sticky sessions means the sessions are sticky once assigned, but mod_jk assigns new sessions to different servers.

              Doing what you want would require some tweaks to distributed sessions. When Tomcat intercepts a request and sends you the login form, it stores info about the original request in a field in the session. Then when you authenticate, it gets the info from the session and uses it to send you to your original destination.

              Right now that "original request info" object isn't replicated, which is why FORM auth doesn't work without sticky sessions. Replicating it *might* not be that big a deal, although IIRC the class Tomcat stores it in doesn't implement Serializable.

              You're more than welcome to open a Feature Request JIRA for it; I'm not at all opposed to the idea, although it will probably be many months before we'd get to it. Unless someone in the community who needs it wants to take a shot at it -- hint, hint ;)

              • 4. Re: Weird apache behaviour in load-balancing, and form-based
                Alberto Rodriguez Newbie

                >>> Unless someone in the community who needs it wants to take a shot at it -- hint, hint ;) <<<

                Got it!! ;-))


                I've been digging Tomcat's code and the info to restore the request after the User has been authenticated is stored in a org.apache.catalina.authenticator.SavedRequest object which as you said is not Serializable and it is stored via setNote(Sting,Object) method of org.apache.catalina.session.StandardSession inherited (and implemented) from org.apache.catalina.Session (so, that's not an standard method of javax.servlet.http.HttpSession as you know).

                A fast peek at JBoss' source code seem to reveal that none of that internal savedrequest notes is neither serialized nor replicated.

                Will it be worth to give it a try to implement replication of that form-based authentication notes in JBoss clustered sessions?

                If so, I would be very pleased to do it but also would appreciate some architectural hints to get the job done.

                Greets

                • 5. Re: Weird apache behaviour in load-balancing, and form-based
                  Brian Stansberry Master

                  Great!

                  Well, the first thing to do is think hard about SavedRequest and see if there is any reason it can't be Serializable. If not, then

                  1) Open a Feature Request JIRA under the Application Server project on jira.jboss.com.

                  2) You need to post a patch to the Tomcat development list making SavedRequest Serializable. I'm not a Tomcat committer, so I can't just commit it for you; needs to be blessed and committed by the TC people. If you want, reference the JIRA issue so they know what you're working toward.

                  3) Then we need to deal with replicating the note itself. In Branch_4_0 you're limited in what you can do, as changing the serialized format of a session is not allowed. So, probably the thing to do is in ClusteredSession override setNote(), check if the key is for your SavedRequest, and if it is also cache the value in a transient field. Then update write/readExternal to store your cached SavedRequest under a special key in the regular attribute map (via setAttribute()). This ensures the SavedRequest is stored in a way that's already part of the existing serialized format. You need to think about this; want to make sure the SavedRequest doesn't remain in the attribute map on either the sender or receiver side, no matter which of the ClusteredSession subclasses is used (SessionBased, FieldBased or AttributeBasedClusteredSession).

                  In HEAD we have more flexibility as to what to do, as it's OK to change the serialized format because there have been no releases of the 5.0.x series yet. I'm tempted to just replicate the notes map (or better yet a copy of it with anything that doesn't implement Serializable removed). But would need to analyze all uses of the map first.