3 Replies Latest reply on Dec 16, 2006 2:09 PM by starksm64

    User credentials lost after remote EJB call

    annie1234

      Hi
      I have a J2EE application that runs on JBoss 4.0.3. The application consists of a web front-end and a EJB 2.1 Stateless Session Bean to implement our business logic.

      Users are authenticated by logging into the web interface. A JAAS LoginModule is used to create a security realm for our web tier (configured in our web.xml & jboss-web.xml files). When a business method is invoked on the SSB the users credentials are correctly propagated to the EJB container (the same security realm has been configured in our jboss.xml file).

      At this stage declarative security (to apply role permissions to EJB methods in ejb-jar.xml) and programmatic security (to access users principal & role using the interface methods SessionContext.getCallerPrincipal().getName() & SessionContext.isCallerInRole("Admin") respectively) work correctly.

      The problem arises when an EJB makes a remote call to another remote EJB on another host with a different username/password . After successfully returning from this remote call our original SSB appears to have an incorrect SesssionContext.

      The remote lookup and operation to the second EJB is done using the following function:

      void changeRemoteBlah(){
      // At this point the SessionContext for the current user on the current local ejb is ok, and we can call local authorized methods
      Properties env = new Properties();
      env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory");
      env.setProperty(Context.SECURITY_PRINCIPAL, "remoteAdmin");
      env.setProperty(Context.SECURITY_CREDENTIALS, password);

      InitialContext ctx = new InitialContext(env);
      Object o = ctx.lookup(jndiRemote);
      BlahManagerRemoteHome home = (BlahManagerRemoteHome) PortableRemoteObject.narrow(o, BlahManagerRemoteHome.class);
      BlahManagerRemote manager = home.create();
      manager.deployBlah();

      return;
      // after the return the SessionContext for the caller EJB is wrong, and we can no longer call our own (local) ejb methods that have authorization on them
      }

      Debug logs after the remote call, upon returning to the 1st EJB:

      org.jboss.security.SecurityAssociation.getSubject,sc=org.jboss.security.SecurityAssociation$SubjectContext@4db02a{principal=remoteAdmin,subject=null}
      org.jboss.security.SecurityAssociation.getPrincipal, cache info: org.jboss.security.plugins.JaasSecurityManager$DomainInfo@7cf002[Subject(27545610).principals=org.jboss.security.SimplePrincipal@28801046(Admin)org.jboss.security.SimpleGroup@2946678(Roles(members:Admin)),credential.class=java.lang.String@5268497,expirationTime=1165984451664

      The getPrincipal call shows the correct original user, however the getSubject call shows the user that was used for the remote call. Does anyone know why this is the case and how to fix it?

      Alternatviely as a workaround solution we have considered storing a local copy of the Users details (SessionContext.getUserRole(), etc) in the method and somehow restore them after completing each remote call to the other ejb. Does anyone know how to to reset these details into the current SessionContext?

      Thanks,
      Annie

        • 1. Re: User credentials lost after remote EJB call
          starksm64

          At a minimum you need to be using 4.0.3SP1. Validation of the behavior under 4.0.5.GA would be the simplest test of whether this issue has been fixed as I believe it has.

          • 2. Re: User credentials lost after remote EJB call
            annie1234

            I have tried this with SP1 & with 4.0.5GA as suggested and still encountered the same problem.

            Just to clarify:
            Before we make the remote call, we can see the original user:

            org.jboss.security.SecurityAssociation.pushSubjectContext,subject=Subject: Principal:AdminPrincipal:Roles(members:Admin),sc=org.jboss.security.SecurityAssociation$SubjectContext@1dadaa{principal=Admin,subject=7645779}
            org.jboss.security.SecurityAssociation.getSubject,sc=org.jboss.security.SecurityAssociation$SubjectContext@1dadaa{principal=Admin,subject=7645779}

            And then when we make the remote call, we can see the remote user being setup:

            org.jboss.security.SecurityAssociation.setCredential,sc=org.jboss.security.SecurityAssociation$SubjectContext@1bb7285{principal=null,subject=null}
            org.jboss.security.SecurityAssociation.setPrincipal,p=remoteAdmin,server=true
            org.jboss.security.SecurityAssociation.setPrincipal,sc=org.jboss.security.SecurityAssociation$SubjectContext@1bb7285{principal=remoteAdmin,subject=null}
            org.jboss.security.SecurityAssociation.getPrincipal,principal=remoteAdmin

            And then we see the original security logs I posted before.

            • 3. Re: User credentials lost after remote EJB call
              starksm64

              The problem is that JndiLoginInitialContextFactory is not designed to be used in a server environment. It should be updated to for this usage:
              http://jira.jboss.com/jira/browse/JBAS-3948

              For now you need to use a jaas login using the org.jboss.security.ClientLoginModule to set the caller for the remote ejb.