问题:

当您UnicastRemoteObject.exportObject(instance)。该实例现在是否对所有客户端公开可用。即使需要一点技巧才能找到其端口。

这种情况:

我有一个Java RMI客户端/服务器设置,我想添加一些身份验证。在其他任何RPC调用起作用之前,允许客户端使用用户/密码组合。

我在网上找到了一个简单的建议,起初看起来是个好主意。

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

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


这个想法是,创建一个远程对象以体现对RPC的经过身份验证的访问。并通过进行身份验证的第一层访问它。

LoginServiceImpl.login()必须看起来像这样。

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;
}


因此,每个调用login()的客户端都会获得其自己的MainService专用远程实例。当然,我会将整个内容包装在ssl中以保护纯文本密码。

这就是问题:

看来,在我导出新的MainServiceImpl实例之后,它现在可以公开使用了。任何其他知道要查找什么内容的客户端都可以连接到该客户端,并在该MainServiceImpl实例上进行调用。

创建MainService后,我必须将其导出,否则RMI不会将存根发送给客户端。相反,它将尝试序列化MainService实例。

我可以将用户名放在MainService中,但这实际上无济于事。

最佳答案

您需要先进行身份验证,然后再切换到JRMP(RMI有线协议)。为此有一个JSR,但它被否决了。 JERI为JINI做到了。

10-07 15:43