10 Replies Latest reply on Oct 23, 2001 9:35 AM by Michael Hussey

    Security Bug

    Lachlan Macpherson Newbie

      Hi,

      Am I right in saying that the StatefulSessionBean handles do no implement security. I tried getting a Handle to a SessionBean so I could use it later but when calling Handle.getEJBObject it appears to have lost the Security Principal and Credentials.

      regards,

      lachlan

        • 1. Re: Security Bug
          Lachlan Macpherson Newbie

          How about doing something like this in
          org.jboss.ejb.plugins.jrmp.interfaces.StatefulHandleImpl


           RemoteMethodInvocation rmi =
           new RemoteMethodInvocation(null,
           GET_EJB_OBJECT,
           new Object[] { id });
           // MF FIXME: WE DEFINITLY NEED THE SECURITY ON SUCH A CALL...
           // We also need a pointer to the TM...:(
          
           // Set the transaction context
           //rmi.setTransaction(tm != null? tm.getTransaction() : null);
          
           // Set the security stuff
           // MF fixme this will need to use "thread local" and therefore same construct as above
           rmi.setPrincipal(SecurityAssociation.getPrincipal());
           rmi.setCredential(SecurityAssociation.getCredential());
           // is the credential thread local? (don't think so... but...)
           // Invoke on the remote server, enforce marshalling
           MarshalledObject mo = new MarshalledObject(rmi);
          


          • 2. Re: Security Bug
            Marc Carrion Newbie

            I think that credentials are not serializable. At least, the credential for the Kerberos Subject. I serialized a subject and I when I read it, the credential wasn't there. I thing it's not a security bug, it's just safer.

            Regards,
            Marc

            • 3. Re: Security Bug
              Lachlan Macpherson Newbie

              Marc,

              Thanks for the reply. I'm still not convinced that this isn't a bug.

              The code I showed before is in the getEJBObject method of the StatefulSessionHandle so is effectively going to happen at the deserialize stage and be able to pick up the credentials that have already been set in the server.

              Also, if the sever does not have a principal authenticated, the

              securityAssociation.getPrincipal())
              and
              securityAssociation.getCredential()
              are going to be null anyway

              regards,

              lachlan

              • 4. Re: Security Bug
                Scott Stark Master

                The handle behavior your seeing is the correct behavior. A handle does not carry security information just as an InitialContext does not. You have to use the handle in a thread context that has established the user identity. Here is a unit test from the security suite that demonstrates this:

                 /** Test the security behavior of handles. To obtain secured bean from
                 a handle, the handle.getEJBObject() method must be invoked with a
                 thread context that has an authenticated user associated with the
                 executing thread.
                 */
                 public void testHandle() throws Exception
                 {
                 System.out.println("+++ testHandle");
                 login();
                 InitialContext jndiContext = new InitialContext();
                 Object obj = jndiContext.lookup("spec.StatelessSession");
                 obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
                 StatelessSessionHome home = (StatelessSessionHome) obj;
                 System.out.println("Found StatelessSessionHome");
                 StatelessSession bean = home.create();
                 System.out.println("Created spec.StatelessSession");
                 Handle h = bean.getHandle();
                 System.out.println("Obtained handle: "+h);
                 bean = (StatelessSession) h.getEJBObject();
                 System.out.println("Obtained bean from handle: "+bean);
                 System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
                 logout();
                
                 /* Attempting to obtain the EJB fron the handle without security
                 association present should fail.
                 */
                 try
                 {
                 bean = (StatelessSession) h.getEJBObject();
                 fail("Should not be able to obtain a bean without login info");
                 }
                 catch(Exception e)
                 {
                 System.out.println("Obtaining bean from handle failed as expected, e="+e.getMessage());
                 }
                
                 // One should be able to obtain a handle without a login
                 h = bean.getHandle();
                 login();
                 // Now we should be able to obtain and use the secure bean
                 bean = (StatelessSession) h.getEJBObject();
                 System.out.println("Obtained bean from handle: "+bean);
                 System.out.println("Bean.echo('Hello') -> "+bean.echo("Hello"));
                 logout();
                 }
                
                


                Output:

                [junit] +++ testHandle
                [junit] Creating LoginContext(spec-test)
                [junit] Created LoginContext, subject=Subject:
                [junit]
                [junit] Found StatelessSessionHome
                [junit] Created spec.StatelessSession
                [junit] Obtained handle: org.jboss.ejb.plugins.jrmp.interfaces.StatelessHandleImpl@2d15a9
                [junit] Obtained bean from handle: spec.StatelessSession:Stateless
                [junit] Bean.echo('Hello') -> Hello
                [junit] Obtaining bean from handle failed as expected, e=Could not get EJBObject; nested exception is:
                [junit] java.lang.reflect.InvocationTargetException
                [junit] Creating LoginContext(spec-test)
                [junit] Created LoginContext, subject=Subject:
                [junit]
                [junit] Obtained bean from handle: spec.StatelessSession:Stateless
                [junit] Bean.echo('Hello') -> Hello


                • 5. Re: Security Bug
                  Lachlan Macpherson Newbie

                  Hi,

                  Thanks for the reply, by the time I have done a handle.getEJBObject() there should be Principal information associated with the thread. All logging-in that I am doing is through the LDAPLoginModule using a login form.

                  Maybe the security information is getting lost somewhere in this scenario, but as far as I am aware, the securtiy association should still be present.

                  regards,

                  Lachlan

                  • 6. Re: Security Bug
                    Scott Stark Master

                    Provide an example that illustrates the problem if you can. At a minimum show the code that obtains that handle and describe why it is executing with a valid security identity if its not obvious from the code.

                    • 7. Re: Security Bug
                      Michael Hussey Newbie

                      I have the exact same problem. I'm using JBoss 2.4.1a. I am using my own LoginModule on the server which extends UsernamePasswordLoginModule.

                      myBean.sampleMethod(); //works
                      Handle handle = myBean.getHandle(); //works
                      myBean = (MyBean) handle.getEJBObject(); //throws security exception.

                      This is the way that I setup my security and initialContext so that I can use my beans (which work fine by the way):

                      public AppCallbackHandler(String username, char[] password)
                      {
                      this.username = username;
                      this.password = password;
                      }

                      public void handle(Callback[] callbacks) throws
                      java.io.IOException, UnsupportedCallbackException
                      {
                      for (int i = 0; i < callbacks.length; i++)
                      {
                      if (callbacks instanceof NameCallback)
                      {
                      NameCallback nc = (NameCallback)callbacks
                      ;
                      nc.setName(username);
                      }
                      else if (callbacks instanceof PasswordCallback)
                      {
                      PasswordCallback pc = (PasswordCallback)callbacks
                      ;
                      pc.setPassword(password);
                      }
                      else
                      {
                      throw new UnsupportedCallbackException(callbacks, "Unrecognized Callback");
                      }
                      }
                      }
                      }

                      //********************** get the context ********************


                      public Context getInitialContext(String sessionKey) throws SabaException {

                      Properties h = new Properties();

                      //identify JBoss specific naming information
                      h.setProperty("java.naming.factory.initial",
                      "org.jnp.interfaces.NamingContextFactory");
                      h.setProperty("java.naming.provider.url", "localhost:1099");
                      h.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

                      //setup username and password
                      String username = null;
                      String password = SabaSessionLoginModule.kNoPassword;
                      if (sessionKey==null) {
                      //login as guest
                      username = SabaSessionLoginModule.kGuest;
                      } else {
                      username = sessionKey;
                      }

                      // now try to create the context...
                      Context result=null;
                      try {
                      result = new InitialContext(h);
                      } catch (Exception e) {
                      //TODO throw SabaException
                      com.saba.util.Debug4.trace(e);
                      throw new FatalException("Unable to obtain context");
                      }
                      //login in under specific username/password
                      try
                      {
                      String site = SabaSite.getSystemDefaultSite().getName();


                      //cannot get the site name from session because
                      // it is looking it up remotely -- should this be the desktop?
                      // if (!username.equals(SabaSessionLoginModule.kGuest)) {
                      // try {
                      // Session sess = SessionManager.getSession(username); //username = sessionkey
                      // site = sess.getSiteName();
                      // } catch (Exception e) {
                      // //just use the default site
                      // site = SabaSite.getSystemDefaultSite().getName();
                      // }
                      // }
                      SabaLogin.setJAASAuthLoginConfig(site);
                      AppCallbackHandler handler = new AppCallbackHandler(username, password.toCharArray());
                      LoginContext lc = new LoginContext("jboss-client", handler);
                      lc.login();
                      }
                      catch (LoginException le)
                      {
                      com.saba.util.Debug4.trace(le);
                      throw new FatalException("Make sure system property java.security.auth.login.config is properly set to "+
                      "include a file with a \"jboss-client\" entry.");
                      }
                      catch (SabaException se)
                      {
                      com.saba.util.Debug4.trace(se);
                      throw new FatalException("Make sure system property java.security.auth.login.config is properly set to "+
                      "include a file with a \"jboss-client\" entry.");
                      }


                      return result;
                      }

                      • 8. Re: Security Bug
                        Michael Hussey Newbie

                        btw, the stack trace on client and server look like this:

                        *******************************************************
                        TestSuite com.saba.utility.testharness.TestSuiteLoginStarted On Fri Oct 05 17:03:51 EST 2001
                        TestCase com.saba.unittest.bframework.locator.TestDelegate Started On Fri Oct 05 17:04:00 E
                        com.saba.rmi.RemoteException : Unexpected internal error
                        java.rmi.ServerException: Could not get EJBObject; nested exception is:
                        java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
                        javax.transaction.TransactionRolledbackException: checkSecurityAssociation; nested exception is:
                        java.lang.SecurityException: Authentication exception, principal=null; nested exception is:
                        java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
                        java.lang.SecurityException: Authentication exception, principal=null
                        at com.saba.util.EjbUtil.convertException(EjbUtil.java:135)
                        at com.saba.locator.ServiceLocator.getEJBObjectFromHandle(ServiceLocator.java:719)
                        at com.saba.locator.DelegateHandleImpl.getDelegate(DelegateHandleImpl.java:88)
                        at com.saba.unittest.bframework.locator.TestDelegate.testDelegateHandleForStateful(TestDelegate.jav
                        at com.saba.unittest.bframework.locator.TestDelegate.testDelegateHandle(TestDelegate.java:84)
                        at com.saba.unittest.bframework.locator.TestDelegate.runTestCases(TestDelegate.java:67)
                        at com.saba.unittest.bframework.locator.TestDelegate.run(TestDelegate.java:62)
                        at com.saba.utility.testharness.TestSuite.run(TestSuite.java:190)
                        at com.saba.utility.testharness.TestManager.main(TestManager.java:195)
                        TestCase com.saba.unittest.bframework.locator.TestDelegate FAILED
                        **********************************************************************************
                        And on the server:
                        **********************************************************************************
                        [AttachmentBuilder] Authentication exception, principal=null
                        [AttachmentBuilder] TRANSACTION ROLLBACK EXCEPTION:checkSecurityAssociation; nested exception is:
                        java.lang.SecurityException: Authentication exception, principal=null; nested exception is:
                        java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
                        java.lang.SecurityException: Authentication exception, principal=null
                        [AttachmentBuilder] java.rmi.RemoteException: checkSecurityAssociation; nested exception is:
                        [AttachmentBuilder] java.lang.SecurityException: Authentication exception, principal=null
                        [AttachmentBuilder] java.lang.SecurityException: Authentication exception, principal=null
                        [AttachmentBuilder] at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:168)
                        [AttachmentBuilder] at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:92)
                        [AttachmentBuilder] at org.jboss.ejb.plugins.StatefulSessionInstanceInterceptor.invokeHome(StatefulSessionInstanceInterceptor.java:123)
                        [AttachmentBuilder] at org.jboss.ejb.plugins.TxInterceptorCMT.invokeNext(TxInterceptorCMT.java:135)
                        [AttachmentBuilder] at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:307)
                        [AttachmentBuilder] at org.jboss.ejb.plugins.TxInterceptorCMT.invokeHome(TxInterceptorCMT.java:86)
                        [AttachmentBuilder] at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:106)
                        [AttachmentBuilder] at org.jboss.ejb.StatefulSessionContainer.invokeHome(StatefulSessionContainer.java:326)
                        [AttachmentBuilder] at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invokeHome(JRMPContainerInvoker.java:370)
                        [AttachmentBuilder] at java.lang.reflect.Method.invoke(Native Method)
                        [AttachmentBuilder] at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
                        [AttachmentBuilder] at sun.rmi.transport.Transport$1.run(Unknown Source)
                        [AttachmentBuilder] at java.security.AccessController.doPrivileged(Native Method)
                        [AttachmentBuilder] at sun.rmi.transport.Transport.serviceCall(Unknown Source)
                        [AttachmentBuilder] at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
                        [AttachmentBuilder] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
                        [AttachmentBuilder] at java.lang.Thread.run(Unknown Source)
                        **********************************************************************************

                        • 9. Re: Security Bug
                          Michael Hussey Newbie

                          Sorry, this is the client stack trace that you'd want:

                          java.lang.SecurityException: Authentication exception, principal=null
                          at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
                          at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
                          at sun.rmi.server.UnicastRef.invoke(Unknown Source)
                          at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invokeHome(Unknown Source)
                          at org.jboss.ejb.plugins.jrmp.interfaces.StatefulHandleImpl.getEJBObject(StatefulHandleImpl.java:124)
                          at com.saba.locator.ServiceLocator.getEJBObjectFromHandle(ServiceLocator.java:717)
                          at com.saba.locator.DelegateHandleImpl.getDelegate(DelegateHandleImpl.java:88)
                          at com.saba.unittest.bframework.locator.TestDelegate.testDelegateHandleForStateful(TestDelegate.java:138)
                          at com.saba.unittest.bframework.locator.TestDelegate.testDelegateHandle(TestDelegate.java:84)
                          at com.saba.unittest.bframework.locator.TestDelegate.runTestCases(TestDelegate.java:67)
                          at com.saba.unittest.bframework.locator.TestDelegate.run(TestDelegate.java:62)
                          at com.saba.utility.testharness.TestSuite.run(TestSuite.java:190)
                          at com.saba.utility.testharness.TestManager.main(TestManager.java:195)

                          • 10. Re: Security Bug
                            Michael Hussey Newbie

                            I guess this is a bug, then, so I'll pursue on the developer list.