1 Reply Latest reply on Jun 16, 2003 11:53 AM by Brian Topping

    Setting up security in a cluster

    Brian Topping Newbie

      Hi all,

      I'm just bringing up my code completely under a cluster for the first time and running into some issues with authentication. Maybe others have seen this before and can make some comments.

      The environment is set up with two login modules under one JAAS realm, both set as "sufficient". One of them is a database driven module (which I believe can be ignored for this discussion), the other is with the UsersRolesLoginModule. All the configuration and code is very robust in an unclustered environment, it seems I'm just having problems with getting authenticated across the cluster. I haven't been able to find anything in the paid docs nor the list archives that addresses issues regarding authentication in a cluster.

      Right now, I am just trying have some client code in the web container of one of the machines call a stateless session bean on each server. When I set up my LoginContext with properties of the localhost:1099, the authentication succeeds and the stateless session bean on the local machine is accessible, but a SLSB on the remote host is not.

      So I figured that the right thing to do was to point the properties for the InitialContext at the HA-JNDI (port 1100), since HA-JNDI first tries the local JNDI, then delegates if it can't find the binding locally. But that fails. It must find the UsersRolesLoginModule okay, because it complains if the users.properties/roles.properties are missing. But when the properties files are in place, they do not have the desired effect -- an AuthenticationException with principal=null is thrown.

      My code looks like:

      Properties params = new Properties();
      params.put(Context.INITIAL_CONTEXT_FACTORY,
      "org.jnp.interfaces.NamingContextFactory");
      params.put(Context.PROVIDER_URL, "localhost:1100");
      params.put(Context.URL_PKG_PREFIXES,
      "org.jboss.naming:org.jnp.interfaces");
      AppCallbackHandler handler
      = new AppCallbackHandler("initial", "initial");
      LoginContext lc = new LoginContext("Bill2Realm", handler);
      lc.login();

      // Obtain initial context
      javax.naming.InitialContext initialContext
      = new javax.naming.InitialContext(params);
      UserManagerHome userManagerHome = null;
      try {
      Object objRef
      = initialContext.lookup(UserManagerHome.JNDI_NAME);
      userManagerHome
      = (UserManagerHome)PortableRemoteObject.narrow
      (objRef, UserManagerHome.class);
      } finally {
      initialContext.close();
      }
      UserManager um = userManagerHome.create();
      // do something nice here...


      Does this ring a bell for anyone? Do I need to configure JAAS to have an auth master in the cluster that I am overlooking? Other than what I did for an unclustered environment, I haven't done anything special to the login configuration.

      Any ideas appreciated, thanks!!

      Brian

        • 1. Re: Setting up security in a cluster
          Brian Topping Newbie

          It turns out that my "client" was running as a servlet. The client login code that is demonstrated in the jboss doco and was in my servlet is overridden by the web container Principal/Credential. Since no login was made there, the principal/credential were null.

          What was strange about the situation is calls to the EJB container from the web container worked fine so long as the EJB container was under the same JVM. Once the two were split, the calls stopped working. My problem arose because there are EJBs that are both local to the web JVM and in a different machine from it. So it was strange that the calls locally were working and the ones remotely were not. That may be an undocumented feature/bug, but I don't know the semantics of the calls as well as I should to determine that.

          In the end, I replaced:

          AppCallbackHandler handler = new AppCallbackHandler("initial", "initial");
          LoginContext lc = new LoginContext("Bill2Realm", handler);
          lc.login();
          // lookup, etc.

          with:

          AuthenticationManager sm = getSecurityManager();
          SimplePrincipal principal = new SimplePrincipal("initial");
          if (sm.isValid(principal, "initial")) {
          if (log.isDebugEnabled()) {
          log.debug("positive auth from JBoss");
          }
          SecurityAssociation.setPrincipal(principal);
          SecurityAssociation.setCredential("initial".toCharArray());
          }
          // lookup, etc.

          I'm not sure if this is a really ugly hack or the right way to be doing this, but it seems to be working okay. If there's a better way to be doing it (I'm also doing this in some app-managed form login code), I'm all ears (pun unintentional...)