7 Replies Latest reply on Jan 5, 2005 12:21 PM by Scott Stark

    Cascading authentication

    Marco Schulze Newbie

      Hello *,

      JBoss is really great, but I still got a problem:

      After hours of analyzing the sources and stepping through them, I figured pretty much out how JBoss manages authentication. I was able to write an own Interceptor and an own LoginModule. Now, nearly all works as it should, but I don't know how to get some information from the InitialContext properties HashMap into the InvocationContext HashMap. Do I need to inherit the ProxyFactory or overwrite the NamingContextFactory or is there an easier way? Please give me a hint.

      Or am I maybe completely on the wrong way?

      Here's my scenario: A user logs in to a server and calls a SessionBean's method. This method should be able to login to a different server (or sometimes the same), but with a different user name and a different password. In the next bean method another delegation can happen. Thus, I need a cascading authentication.

      I first thought, JBoss would do that already, but unfortunately, it doesn't: If I simply work with a LoginContext, it doesn't do what I need:

      class ABean {
      
       public delegateToB()
       {
       LoginContext lc = new LoginContext(
       "myApp",
       new UsernamePasswordHandler(
       userDescriptor.userName,
       userDescriptor.password.toCharArray()));
       lc.login();
       B b = BUtil.getHome(getProperties()).create();
       b.doAsDifferentUser();
       b.remove();
       lc.logout();
      
       C c = CUtil.getHome().create();
       c.doAsOriginalUser();
       c.remove();
       }
      }

      In this example, I cannot work with the "C" bean anymore, because I'm not authenticated. And if I omit the lc.logout(), it tries to execute c.doAsOriginalUser with the wrong user (the one for B).

      After some time I found out that JBoss manages only one current principal in the current thread using SecurityAssociation. Thus, I wrote a client interceptor which creates an additional thread, performs the authentication on the new thread and invokes the other interceptors there. This works fine, but the problem now is that I don't know in the interceptor as which user I should disguise. I saw that there is a Map in InvocationContext and I wonder how I can transfer this information from my InitialContextFactory (the factory knows to which server it should connect as which user) to the interceptor.

      I hope that this posting is understandable even though it's already very late and I'm really tired [;)]

      Please help!

      Best regards, Marco [;)]

        • 1. Re: Cascading authentication
          Marco Schulze Newbie

          I figured it out myself after uncountable hours of debugging and code analysis. And in case anyone of you has the same problem, please feel free to use this solution: http://wiki.nightlabs.de/en/Library:NightLabsCascadedAuthenticationJBoss

          To the jboss team: Would it please be possible to "repair" the org.jboss.security.jndi.LoginInitialContextFactory and integrate the behaviour that I programmed for future releases? The current version of this class is just not usable within the server...

          And in case anyone has a better solution, please let me know: marco -a-t- nightlabs -d.o.t- de

          Best regards, Marco :-)

          • 2. Re: Cascading authentication
            Scott Stark Master

            Using the restore-login-identity=true option to the ClientLoginModule will allow the given code fragment to work as is. You login as a different user and logout restores the original user.

            This is documented in the ClientLoginModule wiki page:
            http://www.jboss.org/wiki/Wiki.jsp?page=ClientLoginModule

            • 3. Re: Cascading authentication
              Marco Schulze Newbie

              First I wish a happy new year to everyone!!!

              Scott, thank you very much for your help! It's a really useful information and I've updated our wiki with it.

              But anyway, IMHO it's quite error prone to manually login and logout whenever accessing a certain "backhand" connection (especially if you have many of them). In my opinion, it is much more logical, that the connection knows its identity and doesn't try to authenticate with the wrong credentials later.

              I mean, if you obtained two beans on two different servers (maybe you got them from a different layer in your app), you cannot just use them but you need to manually take care in your code wich one to access with which identity.

              Well, after I've already programmed a solution, would it be possible to integrate it into JBoss (to avoid it breaking in future releases)?

              Best regards and my best wishes for 2005!

              Marco ;-)

              • 4. Re: Cascading authentication
                Marco Schulze Newbie

                ...I forgot sth. in my previous post:

                If I call LoginContext.login() within my server bean, my server sided login module is triggered and fails! This is clear, because my server login module on server0 cannot authenticate user1@server1.

                Here's an excerpt of my login-config.xml:

                <application-policy name = "ipanema">
                 <authentication>
                 <login-module code = "org.jboss.security.ClientLoginModule" flag = "required"/>
                 <login-module code = "com.nightlabs.ipanema.base.IpanemaServerLoginModule" flag = "requir
                 </authentication>
                </application-policy>
                With my solution, it all works fine, because it doesn't trigger the IpanemaServerLoginModule when my server behaves as a client to another server (the ClientLoginModule is only needed for JSP web apps). How can I avoid my server login module from being triggered with your proposed solution?

                Best regards, Marco ;-)

                • 5. Re: Cascading authentication
                  Scott Stark Master

                  The client jaas context is seperate from the server jaas context. The client login configuration should not include the IpanemaServerLoginModule. Simply use the client-login configuration and switch the identities as needed. I don't find your solution as typical since one typically wants a clear association of what security context is associated with the current thread.

                  • 6. Re: Cascading authentication
                    Marco Schulze Newbie

                    Hi Scott,

                    thanks a lot for your answer!

                    "scott.stark@jboss.org" wrote:
                    The client jaas context is separate from the server jaas context. The client login configuration should not include the IpanemaServerLoginModule.
                    As far as I understand it, there is only one login-config.xml, right?! So how can I differentiate between client and server within my JBoss server? The security configuration seems to be a VM wide singleton, thus I don't understand how to implement your suggestion. To avoid misunderstandings: My JBoss server acts as server AND client, because it needs to connect to other JBoss servers under certain circumstances. The other JBoss servers run the same application (thus, having the same security context named "ipanema").

                    "scott.stark@jboss.org" wrote:
                    Simply use the client-login configuration and switch the identities as needed. I don't find your solution as typical since one typically wants a clear association of what security context is associated with the current thread.
                    Probably you're right that what we do is not typical, because it is typical to work with only one server and one client. But in case, you work with multiple servers, it is not logical anymore that you need to manually keep track on who you are for which EJB proxy. It is IMHO logical, that you create an initial context for every server with which you want to work and everything else works automatically. I think that is what initial contexts and proxies are made for.

                    Best regards, Marco :-)

                    • 7. Re: Cascading authentication
                      Scott Stark Master

                      You control the JAAS login module context of the client by choosing the name passed to the LoginContext, (LoginContext("client-login, ...) for example). The deployer controls JAAS Login module context by sepcifying the security-domain. Thus, the client and server have different contexts.

                      I completely disagree with the statement that the InitialContext has anything to do with holding the security context. In jboss the naming transport and connection may have nothing to do with the ejb or other secured resources. This never has been specified in any j2ee spec and the only reason we allow this pathway is for compatibility with other servers which did not adopts JAAS as quickly as jboss.