p牛在知识星球里问了一个问题:Tomcat中这三个StandardContext、ApplicationContext、ServletContext都是干什么的
skay师傅给出了自己的理解:https://mp.weixin.qq.com/s/BrbkTiCuX4lNEir3y24lew
这里来讲一讲我的理解,说的不一定对,仅供参考。
Context
context是上下文的意思,在java中经常能看到这个东西。那么到底是什么意思呢?
根据我的理解,如果把某次请求比作电影中的事件,那么context就相当于事件发生的背景。例如一部电影中的某个镜头中,张三大喊“奥利给”,但是只看这一个镜头我们不知道到底发生了什么,张三是谁,为什么要喊“奥利给”。所以就需要交代当时事情发生的背景。张三是吃饭前喊的奥利给?还是吃饭后喊的奥利给?因为对于同一件事情:张三喊奥利给这件事,发生的背景不同意义可能是不同的。吃饭前喊奥利给可能是饿了的意思,吃饭后喊奥利给可能是说吃饱了的意思。在WEB请求中也如此,在一次request请求发生时,背景,也就是context会记录当时的情形:当前WEB容器中有几个filter,有什么servlet,有什么listener,请求的参数,请求的路径,有没有什么全局的参数等等。
ServletContext
ServletContext是Servlet规范中规定的ServletContext接口,一般servlet都要实现这个接口。大概就是规定了如果要实现一个WEB容器,他的Context里面要有这些东西:获取路径,获取参数,获取当前的filter,获取当前的servlet等
1 | package javax.servlet; |
ApplicationContext
在Tomcat中,ServletContext规范的实现是ApplicationContext,因为门面模式的原因,实际套了一层ApplicationContextFacade。关于什么是门面模式具体可以看这篇文章,简单来讲就是加一层包装。
其中ApplicationContext实现了ServletContext规范定义的一些方法,例如addServlet,addFilter等
StandardContext
StandardContext存在于org.apache.catalina.core.StandardContext。
实际上研究ApplicationContext的代码会发现,ApplicationContext所实现的方法其实都是调用的this.context中的方法
而这个this.context就是一个实例化的StandardContext对象。
所以在我看来,StandardContext是Tomcat中真正起作用的Context,负责跟Tomcat的底层交互,ApplicationContext其实更像对StandardContext的一种封装。
用下面这张图来展示一下其中的关系
回过头看内存马。以添加filter为例,从上面的分析我们可以知道ApplicationContext跟Standerdcontext这两个东西都有addFilter的方法。那么实际选用哪一个呢?其实两种办法都可以。三梦师傅在基于tomcat的内存 Webshell 无文件攻击技术这篇文章里是利用反射修改了Tomcat的LifecycleState,绕过限制条件调用的ApplicationContext中的addFilter方法。
但是因为实际上最终调用的还是StandardContext的addFilter方法,所以我们就可以直接调用StandardContext的addFilter方法进行绕过,从而省去了绕过一堆判断的过程。这种实现具体可以看这个师傅的公众号文章。