5 Replies Latest reply on Jun 25, 2005 5:00 AM by ebrain13

    Using principal for context passing

    Thomas Cherel Novice


      I have done some reading about being able to transparently (without changing method signature) pass context information across the different tiers and components of an app server.
      It seems that WebSphere provides this Work Area service (JSR 149), WebLogic does not provide anything (except a sample using ThreadLocal variables) and I did not find anything for JBoss.

      I do not like the ThreadLocal variable approach as I want this context to be propagated across multiple J2EE containers and applications (multiple ears) and I do not have any guarantee that the same thread will be used throughout the stack.

      Here is what I prototyped: a JAAS login module that must be added at the end of the JAAS module stack. This module does not do any authentication. It is just replacing or creating a CallerPrincipal for the authenticated subject and generating a "session id" stored in this CallerPrincipal.
      Any session bean code can then retrieve this principal and the session id that can then be used as a key to get or add some objects in a cache like JBossCache.

      It seems to work fine, but I'd like to get some feedback on the validity of the approach. Some of the questions that I am asking myself are as follow:

      - In a clustered environment, is the principal fully replicated so the session id is available on all the nodes of the cluster?

      - As the authenticated subject is cached (to avoid authentication cost at each call), it can also be removed from the cache automatically (and my session id is lost at this point). Does it make sense to tie this mechanism with the notion of session expiration?

      - Am I missing something else that could just break this approach completely?

      - Will it work as well if I have a servlet front-end? For that one, I definitely need to do more reading about how authentication I handled between the servlet and the ejb container.

      Thanks in advance for any suggestions or pointers.

      Thomas

        • 1. Re: Using principal for context passing
          Scott Stark Master

          What the hell, nearly 18 months after the jsr 149 expert group was formed there is not even so much as a draft?

          We already have a detached invoker framework that allows for propagation of context with calls. Coupling this info to the security context does not make sense to me. Do you have any more technical details on the Work Area Service for J2EE api? This should be relatively simple to implement on top of the existing invoker framework.

          • 2. Re: Using principal for context passing
            Thomas Cherel Novice

            Thanks for the feedback.

            I agree, it does not seem that JSR 149 is going anywhere (not sure why).
            The only details that I have on the webSphere implementation is their documentation (http://publib.boulder.ibm.com/infocenter/ws51help/index.jsp?topic=/com.ibm.wasee.doc/info/ee/ae/rprf_workareatune.html for an overview and http://publib.boulder.ibm.com/infocenter/ws51help/index.jsp?topic=/com.ibm.wasee.doc/info/ee/ae/rprf_workareatune.html for an example).

            I agree that it sounds weird to add this to the security context although, from a pure JAAS point of view, the session id of an authenticated user can fit the profile of a Subject principal, I think.
            I am just working around the fact that the full Subject is not available in my EJB code, unless I write my own security interceptor to do a doAs call and use the Subject.getSubject method. But I am not sure how well that will work across EARs and class loaders and I am not sure I want to enable the full blown Java 2 security in my environment.

            I am also looking for a portable (WebSphere, WebLogic and JBoss) way to make this work. I did not find enough hooks in WebLogic (yet) to implement the

            Thomas

            • 3. Re: Using principal for context passing
              Scott Stark Master

              So the Work Area Service for J2EE is a caller initiated session created using the UserWorkArea jndi binding with the call boundaries set by the begin/complete calls:

              package com.ibm.websphere.workarea;
              
              public interface UserWorkArea {
               void begin(String name);
               void complete() throws NoWorkArea, NotOriginator;
              
               String getName();
               String[] retrieveAllKeys();
               void set(String key, java.io.Serializable value)
               throws NoWorkArea, NotOriginator, PropertyReadOnly;
               void set(String key, java.io.Serializable value, PropertyModeType mode)
               throws NoWorkArea, NotOriginator, PropertyReadOnly;
               java.io.Serializable get(String key);
               PropertyModeType getMode(String key);
               void remove(String key)
               throws NoWorkArea, NotOriginator, PropertyFixed;
              }
              


              Like I said, this is something that could be built on top of the current invoker implementation using a valve/filter in the web tier and interceptors in the ejb proxy and container.

              • 4. Re: Using principal for context passing
                Thomas Cherel Novice


                After continuing doing some research on the subject, I am still coming back to the idea of using the principal to do that.

                The main reason for me to do that is this is the only way I found to do something that have a chance to work on "all" (WebSphere, WebLogic and JBoss) application servers without being too much app server proprietary.

                Using the principal comes down to writing a specific JAAS login module that will create a custom principal with a session id.
                At least, a decent amount of code can be shared across the different app server, compared to an interceptor solution on JBoss, a work area one on WebSphere and not sure what on WebLogic (I did not find a way to do that in WebLogic except principal).

                When you said that coupling this with the security context did not make sense, is it just from a pure architecture point of view or do you foresee some potential problems?
                I did not do enough testing yet, but the following areas might cause some issues with the principal solution:

                1) Cluster environment. Is the principal fully replicated in a cluster environment (so session id is replicated with it)?

                2) Cached principal timeout. What does it mean for the associated session if authentication is performed again (and potentially a new session id is created).

                3) Is it possible that in some application server the principal returned by EJBContext.getCallerPrincipal is shared between all the sessions that have been authenticated with the same user id and password? After all, this principal is used only to figure out roles memberships so it should not be a problem if it is shared.


                Thomas



                • 5. Re: Using principal for context passing
                  ebrain13 Newbie

                  After going through this posts, we have implemented the passing of context ( in our case an id ) during a transaction using the interceptors at ejb proxy and container level as suggested by Scott.

                  As such the Invocation object, which has holds the payload to be used during the chain of invocation, didn't retain our value set during the whole transaction, so we had to use ThreadLocal objects, to propogate the id.

                  Moreover couldnt find a better way of injecting the "id", than tampering with the Principal object. ( The "id" injected as the name of the caller principal is used by the entities to query an in memory datastructure to get the current transaction context).

                  The above implementation works, need to do so rigorous testing, but it works.


                  Is it safe to use ThreadLocal objects in Interceptors?
                  Is there a better way to inject an "id", rather than tampering Principal?

                  Please suggest.

                  Thanks
                  Vikram.