在 Tomcat 部署的应用里,我们一般意义上都是指普通的应用,大家可以执行的操作等都是一样的,一条起跑线上的,没有区别。
我们提供的服务有:成都网站设计、成都网站建设、微信公众号开发、网站优化、网站认证、鹤岗ssl等。为上千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的鹤岗网站制作公司
但对于一些特殊的应用,需要执行一些特别的操作,比如官方默认提供的 manager应用,可以进行应用的启动、停止、部署等一系列操作。这些操作的背后,是 Tomcat默认包含的 ManagerServlet 实现的, manager 应用实现的,是对于该 Servelet 的调用。
那我们自己写一个应用去调用这个 ManagerServlet 不也一样可以吗?
答案是不行的,至少直接操作不行,需要配置。这里就是我们今天提到的 Tomcat 内的特权应用(privileged app)。
manager 应用就是自带的一个特权应用,因此它可以直接调用 ManagerServlet 进行一些容器内部的操作。
我们单独部署的其他应用,就会被限制调用这些容器提供的内部组件,比如一些 Servlet、Filter、Listener。
这些限制资源进行检查时,分为两种类型。
1. 一类是通过类型来进行判断,比如 Servlet 中,ManagerServlet、HTMLManagerServlet 这些都被称为ContainerServlet。实现了相同的接口。
2. 还有一类是在配置文件中指定的,有三个文件:
位于 org.apache.catalina.core 包中。
这些内部在 DefaultInstanceManager 初始化时进行解析,例如 servlet的内容解析后是这些:
这些内容也是容器提供的一些功能的实现,比如 GCI 请求处理, JMXProxyServlet 会将 JMX 的属性 dump 出来等等。
特权应用的配置
那怎样能让单独开发的应用成为特权应用,能调用这些容器的功能呢?
之前的文章介绍过应用的部署描述文件context.xml ( Tomcat目录部署与Context描述文件context.xml),这次我们的升级特权操作也是需要在这里进行。
具体来说,在应用部署时,将应用的 Context 对象中 privileged属性设置为 true。例如 manager 应用的配置是这样的,文件位于于 manager 的META-INF 目录中,单独开发时可以参考:
这样配置之后,在应用部署时就会将代表应用的 StandardContext 对象中 privileged 属性设置为true,后面会读取使用。
特权应用的工作原理
应用在启动时,会将 DefaultInstanceManager 做为其 instanceManager。该属性在后面 Servlet、Filter、Listener 这些组件加载时使用,做为实例管理器,进行 newInstance的管理。
以 Servlet 为例,有些 loadOnStartup 的 Servlet,会在部署启动应用时直接生成实例。
在 loadServlet 阶段时,会先通过 Wrapper 获取父容器 Context 的 instanceManager,再通过 instanceManager 来加载具体的 Servlet class。
以下为 instanceManager 进行 newInstace 时的逻辑
- public Object newInstance(String className) {
- Class> clazz = loadClassMaybePrivileged(className, classLoader);
- return newInstance(clazz.newInstance(), clazz);
- }
在loadClassMaybePrivileged中,对于catalina包中的 class,会使用ServerClassLoader 来进行加载,除了通过不同的classLoader加载外,还会进行上面说的 privileged 检查。
- private void checkAccess(Class> clazz) {
- if (privileged) {
- return;
- }
- if (Filter.class.isAssignableFrom(clazz)) {
- checkAccess(clazz, restrictedFilters);
- } else if (Servlet.class.isAssignableFrom(clazz)) {
- if (ContainerServlet.class.isAssignableFrom(clazz)) {
- throw new SecurityException("Restricted (ContainerServlet) " +
- clazz);
- }
- checkAccess(clazz, restrictedServlets);
- } else {
- checkAccess(clazz, restrictedListeners);
- }
- }
- // 这里检查配置文件中的内容
- private void checkAccess(Class> clazz, Properties restricted) {
- while (clazz != null) {
- if ("restricted".equals(restricted.getProperty(clazz.getName()))) {
- throw new SecurityException("Restricted " + clazz);
- }
- clazzclazz = clazz.getSuperclass();
- }
- }
对于 priviledged 应用,之后的 checkAccess 就直接跳过,否则会判断是否是 ContainerServlet,是否在配置文件中进行限制等,只有都检查通过才可以进行 使用。
例如 普通的应用在使用HTMLManagerServlet ,此时由于限制检查,会提示500。
所以,之后有需要使用容器提供的功能时,可以将应用升级为特权应用,然后调用容器提供的高级功能。
【本文为专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】
新闻名称:啥,Tomcat里竟然还有特权应用?
URL标题:http://www.shufengxianlan.com/qtweb/news43/146943.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联