Java 使用GWT RPC时的安全性
我在GoogleWebToolkit中有这样一个POJO,我可以从服务器上检索Java 使用GWT RPC时的安全性,java,security,gwt,servlets,javabeans,Java,Security,Gwt,Servlets,Javabeans,我在GoogleWebToolkit中有这样一个POJO,我可以从服务器上检索 class Person implements Serializable { String name; Date creationDate; } 当客户端进行更改时,我使用GWT RemoteServiceServlet将其保存回服务器,如下所示: rpcService.saveObject(myPerson,...) 问题是用户不能更改creationDate。由于RPC方法实际上只是对服务器的HTTP
class Person implements Serializable {
String name;
Date creationDate;
}
当客户端进行更改时,我使用GWT RemoteServiceServlet将其保存回服务器,如下所示:
rpcService.saveObject(myPerson,...)
问题是用户不能更改creationDate
。由于RPC方法实际上只是对服务器的HTTP POST,因此可以通过更改POST请求来修改creationDate
一个简单的解决方案是创建一系列RPC函数,如changeName(stringnewname)
等,但是对于一个具有多个字段的类,每个字段都需要许多方法,并且一次更改多个字段的效率很低
我喜欢拥有一个可以在服务器和GWT客户端上使用的POJO的简单性,但需要一种安全的方法。有什么想法吗
编辑
我正在重新提交一份赏金,看看是否还有其他想法。也许我最初的问题过于关注GWT的细节。实际上,我认为这对于任何使用JavaBeans在安全(servlet容器)和不安全(web浏览器)环境之间传递数据的系统来说都是一个通用问题
编辑2
另外,为了清楚起见,我使用了creationDate
字段作为问题的示例。事实上,我正在使用的代码在许多不同的领域更为复杂。好吧……一个学术(即理论上可能,但非常不切实际)解决方案可能是使用丢弃的公钥(其私钥在服务器上)散列对象的状态。可能是这样的:
rpcService.saveObject(myPerson,...)
再次,考虑这只是一个思想实验…我不建议你实施这样的方法。一般来说,在保护数据安全之前,您必须能够确保客户端上的逻辑没有被篡改。如果客户端不能更改creationDate并使其保持不变,请更改序列化(例如SQL
UPDATE
语句)以不保存该特定字段。它只能从插入中设置(如果设置了自动默认值,它将来自RPC端点服务器或数据库服务器)。我建议您保留单个RPC方法,并使用POJO/bean映射器,如或
- 使用Dozer,可以创建用于将特性从一个对象复制到另一个对象的。如果未在类映射中指定属性,则不会复制该属性
- 对于Gilead,@ReadOnly应该足够了
附带的好处是,您不需要更改数据访问层(假设您有一个)。无论您是否使用ORM,无论是否使用关系数据库。我会使用基于权限的方法:
- 为用户分配角色(例如管理员用户、登录用户、来宾用户等),以及
- 将这些角色与权限相关联(例如,可以读取人名,可以修改人名-可能进一步将其限制为某些人等)
对于来自客户端的每个请求,如果允许用户执行该操作,则在服务器上执行检查。在“创建日期”的情况下,这可能是任何人都不允许的。所以
- 如果请求包含创建日期,则可以显示错误消息或忽略请求
- 如果请求不包含创建日期(通常情况下),则在服务器上创建该日期-或者如果此人已经有创建日期,则重用该日期
客户机通常会通过某种ID(对于新创建的人员可以为null)指定人员,服务器可以使用该ID查找现有人员。篡改ID应该无关紧要,因为用户无论如何只能修改由其权限指定的数据
特殊情况:
如果您实际上必须使用客户端提供的创建日期,因为您想更准确地知道用户单击的时间,那么您唯一能做的就是检查提供的创建日期是否介于上一个请求和当前请求之间。但是,您必须考虑服务器和客户端之间的时钟差异。而且您不能保证精度。为什么不将字段设置为私有,只提供getCreationDate()和no setCreationDate()?您可以忽略不可变字段的值。
如果由于服务器上持久性机制的设置方式而无法实现,那么当请求到达服务器时,从持久性存储中检索POJO的另一个实例,并填充不可变的字段。有人用这种方式篡改了一些你不在乎的领域
当然,加密可能也是一种有助于避免篡改的解决方案。将对象分成两部分。其中一个只包含客户端可以编辑的字段。将这两个对象发送到客户端,但仅在客户端返回可编辑对象时保存该对象。您可以在这里使用继承使您的生活更加简单
如果映射工具没有按您希望的方式弯曲,请实现一个copy()
方法,将所有字段从一个对象复制到另一个对象。那你就可以