简体   繁体   English

如何组织RMI客户端-服务器体系结构

[英]How to organize RMI Client-Server architecture

I am developing a secured Banking service in RMI with a GUI both for Server and Client. 我正在RMI中使用服务器和客户端的GUI开发安全的银行服务。

The Server must be able to log every operations (new User, deleted User, Withdrawal, Lodgement...) The Client will do these operations. 服务器必须能够记录所有操作(新用户,已删除用户,提款,存放...)。客户端将执行这些操作。 As everything is secured, the Client must at first, create an account with a name and a password in the GUI. 由于所有内容均受保护,因此客户端必须首先在GUI中创建一个具有名称和密码的帐户。 After that, the GUI adds the User in the Bank UserList(arrayList) as a new Customer and the User can do several operations. 之后,GUI将用户添加为银行用户列表(arrayList)中的新客户,并且用户可以执行多项操作。 It seems straightforward at first but I think my conception is not correct. 乍一看似乎很简单,但我认为我的想法是不正确的。

Is it correct to send the whole Bank by RMI ? 通过RMI发送整个银行是否正确? Because at first I thought Bank would be the server but I cannot find another way to do that. 因为起初我以为Bank是服务器,但是我找不到其他方法来做到这一点。 Currently, the Client GUI asks for a login and a password, and receives the Bank by RMI. 当前,客户GUI要求输入登录名和密码,并通过RMI接收银行。 A User is characterized by a name and a hash of the password. 用户的特征是名称和密码的哈希值。

private String name;
private byte[] passwordDigest;

In fact the GUI is doing every security checking and I don't know if it's relevant. 实际上,GUI正在进行所有安全检查,我不知道它是否相关。 When you type login//password, it will search the login in the Bank and compare the hash of the password. 当您键入login // password时,它将在Ba​​nk中搜索登录名并比较密码的哈希值。 In fact I have the impression that the Client knows too much information because when you have the Bank you have everything.. 实际上,我的印象是客户了解太多信息,因为当您拥有银行时,您便拥有了一切。

Does it seem correct or do I need to change my implementation ? 看起来是正确的还是我需要更改实现?

You need two remote object classes. 您需要两个远程对象类。

The first one is obtained via Naming.lookup() ; 第一个是通过Naming.lookup()获得的; it is a singleton; 这是一个单身人士; and it contains a login() method. 它包含一个login()方法。

This method returns the second remote object, which is not a singleton, not registered in the Registry, and is created anew for every return value. 此方法返回第二个远程对象,该对象不是单例,未在注册表中注册,并且为每个返回值重新创建。 This object contains all the banking methods and also a logout() method, which unexports it; 该对象包含所有银行业务方法以及一个logout()它的logout()方法。 it probably also implements the Unreferenced interface so it can detect a dead client, and unexport itself. 它可能还实现了Unreferenced接口,因此它可以检测到已死的客户端并自行导出。 Because it exists once per client, it can hold client state, and because it can only be obtained by a successful login step it solves your security problem. 由于每个客户端仅存在一次,因此它可以保持客户端状态,并且只能通过成功的登录步骤来获取它,因此可以解决您的安全问题。

public interface Login extends Remote
{
    Session login(String username, char[] password /* or whatever */)
        throws LoginException, RemoteException;
}

public interface Session extends Remote
{
    void logout() throws RemoteException;
    void deposit(...) throws RemoteException;
    void withdraw(...) throws RemoteException;
}

public class LoginImpl extends UnicastRemoteObject implements Login
{
    public Session login(String username, char[] password)
        throws LoginException, RemoteException
    {
        // username/password check; if it fails throw a LoginException
        return new SessionImpl(username); // or whatever
    }
}

public class SessionImpl extends UnicastRemoteObject implements Session, Unreferenced
{
    public void logout() throws RemoteException
    {
        unexportObject(this, true);
    }

    public void unreferenced()
    {
        unexportObject(this, true); // needs to be in a try/catch block of course
    }

    // etc
}

I described this as the Remote Session pattern in my book in 2001. 我在2001年的书中将其描述为远程会话模式。

Of course you also need transport layer security: see javax.rmi.ssl. 当然,您需要传输层安全性:请参见javax.rmi.ssl.

You are misunderstanding how Remote interfaces work. 您误解了远程接口的工作方式。 the client does not have the Bank, it only has a reference to a remote instance of a Bank. 客户端不具有银行,它只有到银行的远程实例的引用。 all the method calls made by the client on the Bank interface are actually turned into remote calls against the remote instance of the Bank (running in the server). 客户端在Bank接口上进行的所有方法调用实际上都转换为针对Bank的远程实例(在服务器中运行)的远程调用。

presumably, the security checking is done inside the Bank methods on every method call . 据推测,安全检查是在每个方法调用上在Bank方法内部完成的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM