准备工作
启动该项目
可以看到没有登录时候,cookie中没有rememberme字段
登录时候
当账号密码输入正确时候
登录后存在该字段
shiro特征:
未登陆的情况下,请求包的cookie中没有rememberMe字段,返回包set-Cookie⾥也没有deleteMe字段
登陆失败的话,不管勾选RememberMe字段没有,返回包都会有rememberMe=deleteMe字段
不勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段。但是之后的所有请求中Cookie都不会有rememberMe字段
勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段,还会有rememberMe字段,之后的所有请求中Cookie都会有rememberMe字段
开始分析:
首先找到org/apache/shiro/web/mgt/CookieRememberMeManager.java
进入之后我们点击如下结构,然后来分析
我们点击结构中的类
发现这是一个记住cookie操作的类,包含private Cookie cookie;这里的cookie就是我们网站中的cookie,还有一些涉及cookie的方法
接下来我们看看getRememberedSerializedIdentity()类,这个类是判断我们的cookie值是否是base64,如果是就解码,然后返回解码的值
那么我们看看哪个调用了getRememberedSerializedIdentity
可以看到总共调用有三处,两处是注释,,那么调用处在393行
可以看到调用中参数为subjectContext,也就是我们的cookie,转换成字节数组bytes,然后进入if语句判断是否为空,然后进入principals = convertBytesToPrincipals(bytes, subjectContext);语句,convertBytesToPrincipals这个看字面意思是字节转换成主字节,那么我们跟进去看看
可以看到该函数convertBytesToPrincipals是判断是否为空,不为空就进入到decrypt函数,decrypt函数出来最终还是到了return deserialize(bytes);
一看名字就是反序列化函数
那么我们进入看看deserialize函数
可以看到要用到deserialize函数,那么我们进入再看看
可以发现它是个接口,那么我们需要看他怎么实现的
可以很明显的看到这里有jdk反序列化的操作
这就在最里面了,然后我们回到之前的,开始往前推
那么我们现在知道了这里返回的是一个反序列化的内容,然后我们看这里的
我们跳进去decrypt,
这是用cipherService获取他的类型,然后判断是否为空,不为空就进入里面执行
我们来看看下面这个是什么
跳进去
返回了decryptionCipherKey,那么我们看看他从哪拿到的
那么跳进去decryptionCipherKey
可以看到他是一个private的字节数组,从AbstractRememberMeManager类中设置的
然后我们看看decryptionCipherKey值在哪里被调用
可以看到是在这里设置值的,在setDecryptionCipherKey方法中
那么我们再看看setDecryptionCipherKey方法被谁调用
可以看到是在这里被调用的,在setCipherKey方法中
那么我们再看看setCipherKey方法被谁调用
可以看到是在这里被调用的,在AbstractRememberMeManager方法中
这里好像是构造了,那么我们看看DEFAULT_CIPHER_KEY_BYTES是什么
跳进去
发现了硬编码,默认key值进行base64解码