1 Reply Latest reply on Jan 12, 2014 7:29 PM by Brian Wallis

    AS6 LoginContext and PolicyContext

    Brian Wallis Master

      I have an old RMI interface into an application running in JBoss AS6.1 (and JDK 1.6). It is using the Command Object pattern with a UnicastRemoteObject as the RMI object. We need to get this working with JAAS authentication.

       

      Our application is using the usual LoginModules with a configured security context to authenticate web users using FORM authentication. Once a web user is logged in, we can get the current principal using

       

      Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
      if(subject != null)
      {
        Set<CpfPrincipal> cpfPrincipals = subject.getPrincipals(CpfPrincipal.class);
        ...
      }
      

       

      The principal we set in our login module is of type CpfPrincipal and so we now have our principal and get the current user identity from it amongst other things setup at authentication time.

       

      To authenticate the RMI object, which contains a username and password, we do the following

       

      CallbackHandler handler = new UsernamePasswordHandler(username, password);
      LoginContext lc = new LoginContext("CPF", handler); // same context as used for web logins
      lc.login();
      // after this returns the user is authenticated, so the following gets the subject and principal
      Subject sub = lc.getSubject();
      Set<CpfPrincipal> cpfPrincipals = sub.getPrincipals(CpfPrincipal.class)
      

       

      But if we use the PolicyContext to get the authenticated subject we get back null and so cannot get the principal

       

      Should this work? If not, how can I reliably get the authenticated subject after the above authentication for my RMI method as well as after a standard FORM based web login? I thought that was what PolicyContext was for.

       

      thanks.

        • 1. Re: AS6 LoginContext and PolicyContext
          Brian Wallis Master

          To answer my own question, PolicyContext doesn't seem to work outside of a JEE container.

           

          So, I've wrapped my code that is executed from the RMI call inside a stateless EJB and authenticate before invoking the EJB using the "client-login" domain. Something like this is working:

           

          InitialContext     context            = new InitialContext();
          String             jndiName           = "udr-ear/EJBCommandExecuter/no-interface";
          final EJBCommandExecuter   executer      = (EJBCommandExecuter) context.lookup(jndiName);
          
          
          LoginContext loginCtx = null;
          try {
              // This is usually set from a servlet filter (UserSessionFilter) for http connections,
              // we need to do it here using the client info from the RMI connection. Audit trail
              // log messages require that the client IP is available.
              UserSessionUtility.setCurrentUserIP(getClientHost());
          
          
              LoginCallbackHandler handler = new LoginCallbackHandler(userName, password);
              loginCtx = new LoginContext("client-login", handler);
              loginCtx.login();
          
          
              executer.execute(new EJBCommandObject()
              {
                  @Override
                  public void run()
                             throws Exception
                  {
                      // execute code that requires JEE security setup
                  }
              });
          }
          finally
          {
              if(loginCtx != null)
              {
                  loginCtx.logout();
              }
          }
          

           

          where EJBCommandObject is

           

          public interface EJBCommandObject
          {
              public void run()
                       throws Exception;
          }
          

           

          and EJBCommandExecuter is

           

          @Stateless
          @TransactionManagement(TransactionManagementType.BEAN) // legacy code manages its own transactions
          @SecurityDomain("CPF")
          public class EJBCommandExecuter
          {
              public void execute(EJBCommandObject object)
                           throws Exception
              {
                  object.run();
              }
          }