3 Replies Latest reply on Mar 9, 2009 6:04 AM by Andreas Bille

    JAAS login/logout behaviour

    Andreas Bille Newbie

      Hello all,

      I would be glad to find a solution to the following problem:

      I do have a client which will do subsequent calls to login and logout to an EJB 3 server. The principal can be relatively complex. There is a "test" called EJB - method, which simply returns the name of the callerPrincipal set in the sessionContext.

      The following test code works:

      final SecurityClient client = SecurityClientFactory.getSecurityClient(JBossSecurityClient.class);
      client.setSimple("ln=admin,oce=org_A", "passwd");
      client.login();

      final InitialContext ctxt = new InitialContext();
      final AdministrationServiceRemote adminService = (AdministrationServiceRemote) ctxt
      .lookup("cm3ear/AdministrationService/remote");
      System.out.println(adminService.test());

      giving the expected output

      ln=admin,oce=org_A.

      Now I change the code to

      final SecurityClient client = SecurityClientFactory.getSecurityClient(JBossSecurityClient.class);
      client.setSimple("ln=admin,oce=org_A", "passwd");
      client.login();

      final InitialContext ctxt = new InitialContext();
      final AdministrationServiceRemote adminService = (AdministrationServiceRemote) ctxt
      .lookup("cm3ear/AdministrationService/remote");
      System.out.println(adminService.test());
      client.logout();
      System.out.println(adminService.test());


      Again, I do get the expected behaviour, that is, after the output
      ln=admin,oce=org_A
      an EJBAccessException is thrown for the second call into adminService.test().

      When I change the code to the following:
      final SecurityClient client = SecurityClientFactory.getSecurityClient(JBossSecurityClient.class);
      client.setSimple("ln=admin,oce=org_A", "passwd");
      client.login();

      final InitialContext ctxt = new InitialContext();
      final AdministrationServiceRemote adminService = (AdministrationServiceRemote) ctxt
      .lookup("cm3ear/AdministrationService/remote");
      System.out.println(adminService.test());
      client.logout();

      client.setSimple("ln=admin,oce=org_B", "passwd");
      client.login();
      System.out.println(adminService.test());


      I would expect the following output:
      ln=admin,oce=org_A
      ln=admin,oce=org_B

      because I loged in with a different user the second time.
      After all, the output is
      ln=admin,oce=org_A
      ln=admin,oce=org_A,
      meaning the JBoss caches the user elsewhere.

      On the server side we can see that the logout method of the configured LoginModule is never called, but only the login method, and this, no matter how often the last test code runs, always exactly two times, namely once for the login name ln=admin,oce=org_A, once for the login name ln=admin,oce=org_B. Nevertheless the second login does not show up in the getCallerPrincipal method.
      There is a server restart necessary to clear the cache.


      Is this behaviour a bug or considered to be correct - because a user has already identified itself and it is considered to be a design error, if he must reidentify itself ?

      Any answers would be appreciated ...

        • 1. Re: JAAS login/logout behaviour
          Andreas Bille Newbie

          Ps. We are using JBoss 5.0.0.GA ...

          • 3. Re: JAAS login/logout behaviour
            Andreas Bille Newbie

            Hello Anil,

            well, I introduced a server side method adminService.logout() doing the following operations:

            public void logout() throws MalformedObjectNameException, NullPointerException, InstanceNotFoundException, MBeanException, ReflectionException {
            final MBeanServer server = org.jboss.mx.util.MBeanServerLocator.locateJBoss();

            final String jaasMgrName = "jboss.security:service=JaasSecurityManager";

            final ObjectName jaasMgr = new ObjectName(jaasMgrName);

            final Object[] params = { "myDomain" };

            final String[] signature = { "java.lang.String" };

            @SuppressWarnings("unused")
            List users = (List) server.invoke(jaasMgr, "getAuthenticationCachePrincipals", params, signature);

            server.invoke(jaasMgr, "flushAuthenticationCache", params, signature);

            users = (List) server.invoke(jaasMgr, "getAuthenticationCachePrincipals", params, signature);

            }


            We called this method before the second login in the previous code. After a second test run with a not restarted server, we get the completly odd behaviour, that the first call in the adminService.logout() method to "getAuthenticationCachePrincipals" returns a list of
            both "ln=admin,oce=org_A" and "ln=admin,oce=org_B".

            After calling "flushAuthenticationCache" the second call to "getAuthenticationCachePrincipals" returns in fact a zero list.

            But oddly this has no effect on the output on clientside ... it still returns wrongly two times the same principal name.

            That is, whatever cache the "flushAuthenticationCache" flushes, it does not seem to be the cache where JBoss caches it's principals.

            Also, a colleague of mine has remarked, that we can get a "SecurityAssociation", and the method SecurityAssociation.getPrincipal always returns the correct user, without any need to flush any cache.
            However, if the sessionContext.getCallerPrincipal is wrong, are the roles correct?

            Secondly, we do think that the client side code should not be aware of any need to call additional mehtods simply to flush a cache, which is an implementation detail on server side ...

            Should we file a bug?

            Regards,
            abille