tags:

views:

225

answers:

1

The Question:

When you UnicastRemoteObject.exportObject(instance). Does that instance now become publicly available to all clients. Even if a little tricky is required to find its port.

This is the situation:

I have a java RMI client/server setup and I wanted to add some authentication. Allowing the client to user a user/pass combo before any of the other RPC calls work.

I found a simple suggestion online that looked like a good idea at first.

interface LoginService implements Remote {
  public MainService login(String username, char[] password) throws RemoteException;
}

interface MainService implements Remote {
  /* all my real rpc calls go here */
}

The idea is, create a remote object to embody the post-authenticated access to RPC. And access it through a first tier that does the authentication.

LoginServiceImpl.login() has to looking something like that.

public MainService login(String username, char[] password) throws RemoteException {
  /* verify username and password */
  MainService service = new MainServiceImpl();
  MainService stub = UnicastRemoteObject.exportObject(service, 0);
  return stub;
}

So each client that calls login() gets its own dedicated remote instance of MainService. Naturally I'd wrap the whole thing in ssl to protect the plain-text password.

This is the problem:

It seems that after I've exported my new MainServiceImpl instance, its now publicly available. Any other client that knows what to look for could connect to it and make calls on that MainServiceImpl instance.

I have to export the MainService after I create it or RMI won't send the stub to the client. Instead it will try to serialize the MainService instance.

I could stick the username in the MainService, but that won't actually help.

A: 

You need to do authentication before switching to JRMP (the RMI wire-protocol). There was a JSR for this, but it got voted down. JERI does it for JINI.

Tom Hawtin - tackline
Thats a good solution, but its tricky. Its easy to wrap the rmi in SSL. and its easy to do the auth using RMI inside the ssl connection before allowing access to the important RMI objects. And you can even set that random-ports system property to improve the security of the port chosen. But in the end, I suspect you could still scan for the right port. So the only useful solutions seem to be doing something as low level as the solution suggested in this answer, or sending an auth token on every RMI request (inside the ssl stream).
DragonFax