9 Replies Latest reply on Mar 12, 2008 2:55 AM by alrubinger

    Storing user info on server

      After authentication, I want to store some user information on the server, and have that user information available to subsequent calls (e.g. EJB3 session bean methods). I don't want to have to pass a "user information" object as a method parameter; I want to keep that info on the server and be able to look up the user information based on the authenticated user.

      If this was purely a web application, I would store the information in the HTTP session, and look it up that way. However, my session beans service both web applications and Swing applications that aren't using HTTP. My first thought was to use a SFSB, but how do I store the stub on the server so that I get the same SFSB instance for a given authenticated user? I'd prefer this to be an entirely server-side scheme -- I was hoping to look up the user information in an @AroundInvoke interceptor.

        • 1. Re: Storing user info on server
          alrubinger

          A pattern I've traditionally employed revolves around the notion of an "Application Session", which is stored in any of your client-specific access sessions (ie. Webapp, Flex, GUI). So the application deals with this alone, and is agnostic towards the type of client.

          I'll outline for a webapp here as its probably the most widely used, but you can apply the techniques however you'd like.

          ---

          * End user makes HTTP Request

          * Servlet Filter intercepts before sending along the FilterChain. Grabbing the ApplicationSession, which is an SFSB proxy, from the HttpSession, places in a public static ThreadLocal variable before the invocation continues.

          * There's now an ApplicationSession bound to this request/Thread's scope, usable from any component without having to pass it around or add it to every method signature.

          * On the way out, Servlet Filter (in a finally block) clears the ThreadLocal var holding the SFSB proxy back to intialValue(), otherwise the ApplicationSession will remain tied to this Thread, which will be reused in other requests.

          ---

          So above the parts bound to the webapp are the HttpSession for storing the SFSB and the Filter for placing it in Thread scope. To support another client type, just add the appropriate mechanisms to provide these behaviors.

          S,
          ALR

          • 2. Re: Storing user info on server

            Andrew,

            Thank you for the quick response!

            "ALRubinger" wrote:
            So above the parts bound to the webapp are the HttpSession for storing the SFSB and the Filter for placing it in Thread scope. To support another client type, just add the appropriate mechanisms to provide these behaviors.


            This is where I'm wondering what direction to take. For a non-HTTP client, what would be the best place to store the SFSB proxy? Is there a client-agnostic equivalent to the HttpSession at the container-level? Maybe a HashMap accessed through JNDI (with the Session Principal name as a key)?

            Sorry if I'm being dense -- I'm fairly new to EJBs.

            • 3. Re: Storing user info on server

               

              "jwcone" wrote:
              ...(with the Session Principal name as a key)?...

              Oops -- that should have been the (JAAS) Subject Principal...

              • 4. Re: Storing user info on server
                alrubinger

                 

                "jwcone" wrote:
                Is there a client-agnostic equivalent to the HttpSession at the container-level?


                Well, no. For that you'd have to roll your own.

                This has actually got me thinking quite a bit. :)

                My decision to use a webapp as an example takes for granted encapsulation of a request, and tying this request to a session. And my little mashup also presupposes your web container is in the same JVM as the JEE app. These are some bad assumptions to make.

                So this makes for a pretty neat exercise: how do we model an application request without respect to the type of client?

                I've already addressed the handling of an "Application Session" via a SFSB proxy that's placed in Thread scope for the duration of the request. What we're now missing is a layer capable of storing that proxy to model a "Client Session", and tying it with an "Invocation Request".

                So the responsibilities of this layer would be:

                * Maintain a map of Client Sessions
                * Translate an Invocation Request into the proper executions
                * Register the Application Session with the Thread based on the SFSB stored in the Client Session looked up from something in the payload of the Invocation Request

                You could probably build a whole client-centric invocation framework upon this model, to which many implementations could support. Servlet, Flex, RMI...all become users of this layer which abstracts the client type from the Application itself.

                I'm not really giving you answers here, clearly, but you're spinning my gears.

                Let's take your GUI. You could easily store a SFSB proxy to model your session on the client, and invoke *through* it to access other Services. Problem is, you don't really want to be using a delegate pattern here - any time you add/edit/change a service you'd have to update the SFSB to support that change. But if the SFSB had a more dynamic "invokeService()" method, you could use that to get to your other services. And if the SFSB on your client also had within it a reference to another SFSB (your Application Session), then after you call "invokeService" the container could automatically register your Application Session.

                Food for thought, if nothing else.

                *How do we best implement client-agnostic session handling*?

                Thanks for the fodder for next week's blog, anyway. I'll be thinking more on this.

                S,
                ALR



                • 5. Re: Storing user info on server

                  What about simply using a custom principal on server side, one that contains your user information? This works perfectly, even with stateless session beans, since the principal information is stored in the authentication cache between the server calls.
                  You can easily access the custom principal via the SessionContext.getCallerPrincipal() method.

                  more info on using a custom principal can be found on the wiki:
                  http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingCustomPrincpalsWith


                  • 6. Re: Storing user info on server

                     

                    "roeladriaensens" wrote:
                    What about simply using a custom principal on server side, one that contains your user information?

                    I considered this, but didn't pursue it because it seemed like I would be using the Principal for a purpose it wasn't really intended for. That is, for some types of user information (e.g. a SSN), a custom Principal is appropriate. However, I'm also talking about a more variable, cache-like approach (e.g. storing the currently active account that's being accessed, or a list of account codes the authenticated user is allowed to access -- in my project, a user can access multiple "accounts" which correspond to different database resources, among other things).

                    I guess it would still work. I haven't created a custom Principal, before, though. If I were to do this, would I have any difficulty using the custom Principal as a cache that could be read and written to at run-time (e.g. if the authenticated user changed to a different active account, for example).


                    • 7. Re: Storing user info on server
                      alrubinger

                       

                      "roeladriaensens" wrote:
                      What about simply using a custom principal on server side, one that contains your user information?


                      Great for taking advantage of a backend Authenticated registry, but doesn't account for a conversational session (tying together a series of requests).

                      Probably will fit many requirements, though.

                      S,
                      ALR

                      • 8. Re: Storing user info on server

                        I implemented a custom Principal to hold the additional user information (and a custom LoginModule to populate it in the Group array); that does get the job done, which is good enough, for now.

                        I'll keep an eye on your blog, Andrew; I'm still thinking about an invocation framework that is "client agnostic," so I'll be interested to see your thoughts on that.

                        • 9. Re: Storing user info on server
                          alrubinger

                           

                          "jwcone" wrote:
                          I'll keep an eye on your blog, Andrew; I'm still thinking about an invocation framework that is "client agnostic," so I'll be interested to see your thoughts on that.


                          I'm letting this one brew for a bit so I can consider alternative solutions, if this has yet been addressed, etc.

                          Would have posted per usual last Sunday night, but ended up taking my girlfriend to a wine bar. Turns out that was more rewarding. :)

                          S,
                          ALR