一:Bug描述
A系统集成shiro-redis实现会话共享,将会话序列化到redis。
同域下的B系统根据cookie中的会话token,从redis获取readSession失败,源码调试发现反序列化失败。
二:原因
shiro-redis底层使用Serializable接口序列化方式,writeObject方法将Session对象序列化为byte[]数组后存到redis。
writeObject方法会将对象、类路径、方法签名等详细信息全部序列化。
Session实例中包含认证用户的信息,而UserDTO对象是在A系统定义的,类路径、方法签名等信息在B系统找不到完全一样的类定义,因此反序列化失败。
三:解决
在B系统维护一个包路径、代码定义完全一致的User类。
四:知识点总结
不同系统之间Serializable反序列化:类的路径以及功能代码必须完全相同。
出于安全考虑,还可以使用serialVersionUID作为逻辑补充:
序列化ID是类中的一个final变量,用来唯一标识该类定义。
如果想要跨系统反序列化,则需要 类的完整路径(包路径)以及功能代码完全相同,如果类中有serialVersionUID字段,则该字段值也要相同。