Building Secure Java RMI Servers
by Paulo Marques

Listing One
package authrmi;
/** The interface of the server. */
public interface ServerInterface
   extends java.rmi.Remote
{
   /** The first operation. @throws SecurityException If the client doesn't
   * have permissions for executing this method. */
public void doOperationA()
      throws java.rmi.RemoteException, SecurityException;
   /** The second operation. @throws SecurityException If the client doesn't
   * have permissions for executing this method. */
   public void doOperationB()
      throws java.rmi.RemoteException, SecurityException;
}

package authrmi;
/** The actual implementation of the server. */
public class ServerImpl
   implements ServerInterface
{
   /** The first operation. */
   public void doOperationA()
   {
      System.out.println("Operation A!");
   }
   /** The second operation. */
   public void doOperationB()
   {
      System.out.println("Operation B!");
   }
}


Listing Two
grant Principal authrmi.RMILoginPrincipal "root"
{
   permission authrmi.permissions.ServerPermission "*";
};
grant Principal authrmi.RMILoginPrincipal "alice"
{
   permission authrmi.permissions.ServerPermission "doOperationA";
};
grant Principal authrmi.RMILoginPrincipal "guest"
{
};


Listing Three
package authrmi;
/** Interface for client users to login. */
public interface LoginInterface extends java.rmi.Remote
{
   /** Method that lets clients login, returning an interface to the server.
   * @param username The name of the user.
   * @param password The password of the user.
   * @return A reference to a proxy of the server object.
   * @throws SecurityException If the client is not allowed to login. */
   public ServerInterface login(String username, String password)
      throws java.rmi.RemoteException, SecurityException;
}


Listing Four
package authrmi;

import authrmi.exceptions.*;
import javax.security.auth.*;
import java.util.*;

/** Implements the server object that allows clients to login. */
public class LoginImpl
   extends java.rmi.server.UnicastRemoteObject
   implements LoginInterface
{
   /** The real server object */
   private ServerInterface myServer;
   ////////////////////////
   /** Class constructor. @param theServer The real server object. */
   public LoginImpl(ServerInterface theServer)
      throws java.rmi.RemoteException
   {
      myServer = theServer;
   }
   /** Allows a client to login and get an interface to the server. */
   public ServerInterface login(String username, String password)
      throws java.rmi.RemoteException, SecurityException
   {
      // Creates a subject that represents the user
      Subject user = new Subject();
      user.getPrincipals().add(new RMILoginPrincipal(username));
      // Check if this user can login. If not, an exception is thrown
      // Checks if the user is known and the password matches
      String realPassword = null;
      try
      {
         Properties passwords = new Properties();
         passwords.load(new java.io.FileInputStream(Constants.PASS_FILENAME));
         realPassword = passwords.getProperty(username);
      }
      catch (java.io.IOException e)
      {
         throw new InvalidUserException(username);
      }
      if ((realPassword==null) || !realPassword.equals(password))
      {
         throw new InvalidUserException(username);
      }
      // Return a reference to a proxy object that encapsulates the access
      // to the server, for this client
      return new ServerProxy(user, myServer);
   }
}


Listing Five
package authrmi;
/** Class used for representing an authenticated user in the system. */
public class RMILoginPrincipal
   implements java.security.Principal
{
   /** The username */
   private String username;
   ////////////////////////
   /** Class constructor.  @param username The username of the user. */
   public RMILoginPrincipal(String username)
   {
      this.username = username;
   }
   /** Returns the username of the user. @return The username. */
   public String getName()
   {
      return username;
   }
}


Listing Six
grant codebase "file:authrmi_main.jar"
{
   permission java.security.AllPermission;
};
grant codebase "file:authrmi_actions.jar"
{
};
