当前位置: 首页 > 编程笔记 >

JDK反序列化时修改类的全限定性名解析

公西良骏
2023-03-14
本文向大家介绍JDK反序列化时修改类的全限定性名解析,包括了JDK反序列化时修改类的全限定性名解析的使用技巧和注意事项,需要的朋友参考一下

应用场景

SpringSecurityOAuth2有一个奇葩的设计,那就是它将与access_token相关的所有属于都封装到OAuth2AccessToken中,然后保存时会直接将该对象序列化成字节写入数据库。我们在资源服务器中想要直接读数据库来取出access_token来验证令牌的有效性,然而又不想引入SpringSecurity的相关依赖污染jar包。这时可以将SpringSecurity中OAuth2AccessToken的唯一实现类DefaultOAuth2AccessToken的源码copy到我们的项目中,然后通过JDBC读取byte[],通过JDK自带的反序列化机制来还原DefaultOAuth2AccessToken对象。这时就会遇到问题,即原来的OAuth2AccessToken所在包是以org.springframework.security开头的,而我们copy过来源码后,包名是以我们自己定义的包cn.com.XXXX开头的,这样在反序列化时,即使两个类的字段完全一样,但由于字节流中存储的类信息的全限定性名不同,也会导致反序列化失败。

解决方案

我们可以定义子类继承JDK的ObjectInputStream,然后重写readClassDescriptor()方法:

@Override
    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
	ObjectStreamClass read = super.readClassDescriptor();
	if (read.getName().startsWith("原包名")) {
		Class type = Class.forName(read.getName().replace("新包名"));
		return ObjectStreamClass.lookup(type);
	}
	return read;
}

这样在反序列化时就不会报错了。原理并不复杂,其实就是在解析字节流时,将解析后应为org.springframework.security.oauth2.common.DefautOAuthToken的class,替换成了我们自己copy过来源码的cn.com.XXXXXX.DefaultOAuthToken从而达到”欺骗”的目的。在该场景下,我们就可以做到在资源提供方不引入SpringSecurity框架而只使用SpringSecurityOAuth2的授权服务。资源提供方直接读数据库来验证令牌的有效性,而不是向授权服务查询。

总结

以上就是本文关于JDK反序列化时修改类的全限定性名解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其它相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

 类似资料:
  • 关于这个问题: 如何在使用JSON.NET序列化时更改属性名称? 会像预期的那样反序列化。 作为一个解决方案,没有属性也可以工作,或者类上有一个属性,比如:

  • 假设我们有以下JSON, 在Java类中,我们有与上述JSON匹配的所有字段。 每次要反序列化的字段列表取决于发送信息的客户。 例如,对于customer 1,我们只想读回以下值,(并且跳过其他属性,即使在JSON中提供) 例如,对于客户2,我们希望读取以下值(并跳过其他属性,即使在JSON中提供) 使用Jackson反序列化JSON时,是否可以提供上面的数组,其中包括需要反序列化的字段, 更新:

  • 我正在将RedditAPI中的一些内容反序列化到POJO中。我的目标是尽可能简化代码,因为reddit中实体之间的JSON结构通常是相同的。 例如,反序列化链接对象的JSON如下所示: 我可以反序列化这一点没有问题,但由于reddit注释的不同之处在于其类型为t1,并且在其下方的数据对象中具有不同的结构,因此我希望将相同的类结构重新用于JSON包装,而不必创建多个具有一行或两行差异的复制类。 我创

  • 问题内容: 在这种情况下是否可能发生任何安全漏洞利用: str对象在哪里。该字符串是用户生成的,可能令人讨厌。假设我们的网络框架没有让我们失败,那是一个来自Python内置函数的真正诚实的str实例。 如果这样做很危险,我们可以对输入进行任何操作以使其安全吗? 我们当然 不 希望执行字符串中包含的任何东西。 对于这个问题,我认为不是必不可少的更大范围是,我们有成千上万个这样的环境: 在某些情况下嵌

  • 我正在编写一个使用Jackson序列化/反序列化对象的类。在编译时,我不知道要序列化/反序列化的对象是哪种类型。 我的类看起来像(移除了一些不相关的代码): 这是我用来测试的代码片段: 据我所知,使用应该足以让反序列化器知道从字节流读取的值应该放在对象中。但是,方法返回的对象仍然是,我理解它是反序列化的默认类。 我还尝试更改方法以返回,但我遇到了同样的问题。 我很确定这是关于我将类型传递到序列化器

  • 编辑2:我已经用改型拦截器手动修改响应体来完成这个任务。它是有效的,但如果你有任何其他建议,请发布它们:)