Hessian/Java反序列化采用自定义的Classloader
对于采用OSGi来做系统的人而言,ClassLoader的问题必然是头号需要解决的问题,如果又是个需要远程通讯的OSGi应用的话,那么反序列化的classloader问题几乎可以肯定是会碰到的,来看看在如今流行的两种序列化、反序列化协议:java/hessian中如何使用自定义的classloader。
java/hessian并不提供直接的传入ClassLoader类来改变反序列化时采用的ClassLoader,hessian采用的为使用当前线程的上下文ClassLoader来加载反序列化的类,java则采用堆栈上最近的一个ClassLoader类来加载,可以认为就是调用类所在的ClassLoader来加载,但在OSGi应用中,通常采用以上默认的行为来反序列化加载类是会出问题的,因此需要采用自定义的。
先来看看java的,Java在ObjectInputStream.readObject时最后采用的是resolveClass方法来加载类:
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
String name = desc.getName();
try {
return Class.forName(name, false, latestUserDefinedLoader());
} catch (ClassNotFoundException ex) {
Class cl = (Class) primClasses.get(name);
if (cl != null) {
return cl;
} else {
throw ex;
}
}
}惊喜的是,resolveClass是protected的,:),还好,还留下了这一手,于是毫不客气,写一个继承ObjectInputStream的子类,然后覆盖resolveClass方法即可,到这步了就可以随意用自己的ClassLoader来实现加载了。
OK,java的解决了,来看Hessian的,Hessian在加载类的时候采用了下面的代码:
if (type.startsWith("[")) {
Deserializer subDeserializer = getDeserializer(type.substring(1));
deserializer = new ArrayDeserializer(subDeserializer);
}
else {
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class cl = Class.forName(type, false, loader);
deserializer = getDeserializer(cl);
} catch (Exception e) {
}
}看过这段代码后,就明白,要替换,最明显的一种做法是替换当前线程的上下文classloader,而这通常有一定的风险,因为可能会有很多代码使用到线程的上下文classloader,另外一种可选的做法就是继承SerializerFactory,覆盖其中的getDeserializer方法,从而实现对加载类的ClassLoader的控制,这种方式风险就比较小了。
为了能实现使用自定义的classloader后可以加载到所有bundle export package中的类,在自定义classloader所在的Bundle中需要加上DynamicImport-Package,这样可以比较简单的实现。
在Equinox中,则还可以选择实现ClassLoadingHook,这样可以比较简单的实现和其他外部容器的集成以及更加自如的控制classloader,:)
在解决了classloader的问题后,通常来讲,使用OSGi带给你的更多的就是享受,而非痛苦了。
分享到:
相关推荐
NULL 博文链接:https://qinghua0208.iteye.com/blog/493516
介绍自己不会查吗?这里有一个点就是Hessian的序列化与反序列化与原生序列化与反序列化不同,就以使用的Resin链而言,其中的javax.naming.spi
-a:生成exploit下的所有payload(例如:hessian下的SpringPartiallyComparableAdvisorHolder, SpringAbstractBeanFactoryPointcutAdvisor, Rome, XBean, Resin) -t:对生成的payloads进行解码测试 -v:verbose mode...
Nacos JRaft Hessian 反序列化 RCE 分析.pdf
a --args gadget入参,多个参数使用多次该命令传入,例-a -a Calc-p --protocol [dubbo|http] 通讯协议名称,默认缺省dubbo-s --serialization [hessian|java] 序列化类型,默认缺省hessian-t --target 目标,例:...
NULL 博文链接:https://inter12.iteye.com/blog/1555678
主要通过对二者简单的实现方式的对比,介绍了Java序列化和hessian序列化的差异,具有一定参考价值,需要的朋友可以了解下。
Hessian 2.0序列化协议规范
java8 看不到源码歌海森 注意:解码时,java 版本的 hessian 会默认跳过并忽略不存在的字段。 从 v1.6.0 版本开始,dubbo-go-hessian2 也会跳过不存在的字段,而 v1.6.0 之前的版本会返回错误。 它是一个 golang ...
使用eclipse maven工程搭建hessian远程服务demo 分服务端的整合和客户端 建议阅读相关博客http://blog.csdn.net/heisemuyangquan/article/details/79460528
NULL 博文链接:https://wo-niu.iteye.com/blog/2200720
flex-hessian-java实例~~~~~~~~~~~~~
hessian序列化.pdf
Hessian 接口 Java Python
基于java实现hessian进行服务器之间数据交互demo项目 实现功能: 1.基于spring 2.5.6+hessian3.1.6带有签名安全机制 2.基于servlet代理机制实现HessianServlet,进行简单IP地址校验功能!
hessian php与java通讯demo源码
NULL 博文链接:https://san-yun.iteye.com/blog/1688510
这个是我自己写的一个hessian小例,其中包括两个project,一个是服务端,一个是客户端,代码比较简单,只是为了测试hessian在javaweb项目中的使用
如果数据模型非常复杂,那么Hessian/Burlap的序列化模型可能无法胜任了。 Spring开发团队意识到RMI服务和基于HTTP的服务之前的空白,Spring的HttpInvoker应运而生。 Spring的HttpInvoker,它基于HTTP之上提供...