Apache Tomcat 9

 Apache Tomcat9 版本9.0.14, 2018年12月6日

这是Apache Tomcat Servlet / JSP容器的文档包的顶级入口点 。的Apache Tomcat 9.0版本实现了Servlet 4.0和JavaServer Pages 2.3 规范从 Java社区进程,并包含许多额外的功能,使开发和部署Web应用程序和Web服务的有用平台。

从导航菜单(左侧)中选择一个链接,深入查看可用的更详细的文档。下面更详细地描述了每个可用的手册。

 

Apache Tomcat用户指南

以下文档将帮助您下载和安装Apache Tomcat,并使用许多Apache Tomcat功能。

  1. 简介 - Apache Tomcat的简要,高级概述。
  2. 设置 - 如何在各种平台上安装和运行Apache Tomcat。
  3. 第一个Web应用程序 -Servlet规范中定义的 Web应用程序概念简介。涵盖Web应用程序源代码树的基本组织,Web应用程序归档的结构以及Web应用程序部署描述符(/WEB-INF/web.xml)的简介。
  4. Deployer - 运行Apache Tomcat Deployer以部署,预编译和验证Web应用程序。
  5. Manager -在Apache Tomcat运行时运行 Manager Web应用程序以部署,取消部署和重新部署应用程序。
  6. 主机管理器 - 运行 Host Manager Web应用程序以在Apache Tomcat运行时添加和删除虚拟主机。
  7. 领域和访问控制 - 如何配置领域(用户,密码及其相关角色的数据库)以在使用容器管理安全性的 Web应用程序中使用的说明。
  8. 安全管理器 - 配置和使用Java安全管理器以支持对Web应用程序行为的细粒度控制。
  9. JNDI资源 - 在提供给每个Web应用程序的JNDI命名上下文中配置标准和自定义资源。
  10. JDBC DataSource - 使用数据库连接池配置JNDI数据源。许多流行数据库的示例。
  11. 类加载 - 有关Apache Tomcat中类加载的信息,包括放置应用程序类以使其可见的位置。
  12. JSPs - 有关Jasper配置的信息,以及JSP编译器的用法。
  13. SSL / TLS - 安装和配置SSL / TLS支持,以便您的Apache Tomcat将使用https协议提供请求。
  14. SSI - 在Apache Tomcat中使用服务器端包含。
  15. CGI - 在Apache Tomcat中使用CGI。
  16. 代理支持 - 将Apache Tomcat配置为在代理服务器(或充当代理服务器的Web服务器)后面运行。
  17. MBean描述符 - 为自定义组件配置MBean描述符文件。
  18. 默认Servlet - 配置默认servlet和自定义目录列表。
  19. Apache Tomcat群集 - 在Apache Tomcat环境中启用会话复制。
  20. Balancer - 配置,使用和扩展负载均衡器应用程序。
  21. 连接器 - Apache Tomcat中可用的连接器,以及本机Web服务器集成。
  22. 监控和管理 - 启用JMX Remote支持,并使用工具监控和管理Apache Tomcat。
  23. 日志记录 - 在Apache Tomcat中配置日志记录。
  24. Apache Portable Runtime - 使用APR提供卓越的性能,可伸缩性以及与本机服务器技术的更好集成。
  25. 虚拟主机 - 在Apache Tomcat中配置虚拟主机。
  26. 高级IO - 可通过常规阻塞IO进行扩展。
  27. 附加组件 - 获取其他可选组件。
  28. 将Tomcat库与Maven一起使用 - 通过Maven获取Tomcat jar。
  29. 安全注意事项 - 保护Apache Tomcat安装时要考虑的选项。
  30. Windows服务 - 在Microsoft Windows上将Tomcat作为服务运行。
  31. Windows身份验证 - 配置Tomcat以使用集成Windows身份验证。
  32. 高并发JDBC池 - 配置Tomcat以使用备用JDBC池。
  33. WebSocket支持 - 为Apache Tomcat开发WebSocket应用程序。
  34. URL重写 - 使用基于regexp的重写阀进行条件URL和主机重写。

参考

以下文档面向负责安装,配置和操作Apache Tomcat服务器的系统管理员

Apache Tomcat开发人员

以下文档适用于希望为Apache Tomcat项目开发做出贡献的Java开发人员。

  • 从源构建 - 详细说明下载Apache Tomcat源代码(以及它依赖的其他软件包)所需的步骤,并从这些源构建二进制分发。
  • 更改日志 - 详细说明对Apache Tomcat所做的更改。
  • 状态 - Apache Tomcat开发状态。
  • 开发人员 - 活动Apache Tomcat贡献者列表。
  • 功能规范 -Apache Tomcat的 Catalina servlet容器部分功能的需求规范。
  • Javadocs - Apache Tomcat内部的Javadoc API文档。
  • Apache Tomcat体系结构 - Apache Tomcat服务器体系结构的文档。

 

 

简介 - Apache Tomcat的简要,高级概述

对于管理员和Web开发人员来说,在开始之前,您应该熟悉一些重要的信息。本文档简要介绍了Tomcat容器背后的一些概念和术语。同样,告诉你,当您需要帮助时,去哪里寻求帮助。

术语

在阅读这些文件的过程中,您将遇到许多术语; 一些特定于Tomcat的,以及其他由Servlet和JSP规范定义的 。

  • 上下文 - 简而言之,Context是一个Web应用程序。

这就对了。如果您发现我们需要在此部分添加更多字词,请告知我们。

目录和文件

这些是一些关键的tomcat目录:

  • / bin - 启动,关闭和其他脚本。这些 *.sh文件(对于Unix系统)是*.bat文件的功能重复(对于Windows系统)。由于Win32命令行缺少某些功能,因此这里有一些额外的文件。
  • / conf - 配置文件和相关的DTD。这里最重要的文件是server.xml。它是容器的主要配置文件。
  • / logs - 默认情况下,日志文件在此处。
  • / webapps - 这是您的webapps的用武之地。

CATALINA_HOME和CATALINA_BASE

在整个文档中,引用了以下两个属性:

  • CATALINA_HOME:表示Tomcat安装的根目录,例如/home/tomcat/apache-tomcat-9.0.10 或C:\Program Files\apache-tomcat-9.0.10
  • CATALINA_BASE:表示特定Tomcat实例的运行时配置的根。如果要在一台计算机上拥有多个Tomcat实例,请使用该CATALINA_BASE 属性。

如果将属性设置为其他位置,则CATALINA_HOME位置包含静态源,例如.jar文件或二进制文件。CATALINA_BASE位置包含配置文件,日志文件,已部署的应用程序和其他运行时要求。

为什么使用CATALINA_BASE

默认情况下,CATALINA_HOME和CATALINA_BASE指向同一目录。当您需要在一台计算机上运行多个Tomcat实例时,请手动设置CATALINA_BASE。这样做有以下好处:

  • 更轻松地管理升级到更新版本的Tomcat。由于具有单个CATALINA_HOME位置的所有实例共享一组 .jar文件和二进制文件,因此您可以轻松地将文件升级到较新版本,并使用相同的CATALIA_HOME目录将更改传播到所有Tomcat实例。
  • 避免重复相同的静态.jar文件。
  • 共享某些设置的可能性,例如setenvshell或bat脚本文件(取决于您的操作系统)。

CATALINA_BASE的内容

在开始使用CATALINA_BASE之前,首先考虑并创建CATALINA_BASE使用的目录树。请注意,如果您不创建所有推荐的目录,Tomcat会自动创建目录。如果无法创建必要的目录,例如由于权限问题,Tomcat将无法启动,或者可能无法正常运行。

请考虑以下目录列表:

  • bin与目录setenv.sh, setenv.battomcat-juli.jar文件。

    推荐:不。

    查找顺序:首先检查CATALINA_BASE; 回退提供给CATALINA_HOME。

  • lib具有要在类路径上添加的更多资源 的目录。

    推荐:是的,如果您的应用程序依赖于外部库。

    查找顺序:首先检查CATALINA_BASE; CATALINA_HOME第二次加载。

  • logs目录实例特定的日志文件。

    推荐:是的。

  • webapps自动加载的Web应用程序 的目录。

    推荐:是的,如果要部署应用程序。

    查找顺序:仅限CATALINA_BASE。

  • work包含用于部署的Web应用程序的临时工作目录目录。

    推荐:是的。

  • temp临时文件使用的JVM目录。

    推荐:是的。

我们建议您不要更改tomcat-juli.jar文件。但是,如果您需要自己的日志记录实现,则可以替换tomcat-juli.jar特定Tomcat实例的CATALINA_BASE位置中的文件。

我们还建议您将CATALINA_HOME/conf目录中的所有配置文件复制 到 CATALINA_BASE/conf/目录中。如果CATALINA_BASE中缺少配置文件,则不会回退到CATALINA_HOME。因此,这可能会导致失败。

至少,CATALINA_BASE必须包含:

  • conf/server.xml中
  • conf/web.xml文件

那包括conf目录。否则,Tomcat无法启动或无法正常运行。

有关高级配置信息,请参阅 RUNNING.txt 文件。

如何使用CATALINA_BASE

CATALINA_BASE属性是一个环境变量。您可以在执行Tomcat启动脚本之前进行设置,例如:

  • 在Unix上: CATALINA_BASE=/tmp/tomcat_base1 bin/catalina.sh start
  • 在Windows上: CATALINA_BASE=C:\tomcat_base1 bin/catalina.bat start

配置Tomcat

本节将使您了解容器配置期间使用的基本信息。

配置文件中的所有信息都在启动时读取,这意味着对文件的任何更改都需要重新启动容器。

寻求帮助

虽然我们已尽最大努力确保这些文件清晰易读,但我们可能错过了一些内容。下面提供了各种网站和邮件列表,以防您遇到困难。请记住,Tomcat的主要版本之间的一些问题和解决方案各不相同。当您在网上搜索时,会有一些与Tomcat 9无关的文档,但仅限于早期版本。

  • 当前文档 - 大多数文档将列出潜在的挂起。请务必完整阅读相关文档,因为这样可以节省您的大量时间和精力。没有什么比搜索网络只是为了找到答案就在你面前一直在你面前!
  • Tomcat FAQ
  • Tomcat WIKI
  • jguru的 Tomcat常见问题解答
  • Tomcat邮件列表存档 - 众多站点存档Tomcat邮件列表。由于链接会随着时间的推移而变化,点击此处将搜索 Google
  • TOMCAT-USER邮件列表,您可以在订阅 。如果您没有得到答复,那么很可能您的问题可能会在列表存档或其中一个常见问题解答中得到解答。虽然有时会询问和回答有关Web应用程序开发的问题,但请将您的问题集中在Tomcat特定的问题上。
  • TOMCAT-DEV邮件列表,您可以在订阅 。此列表 保留用于讨论Tomcat本身的开发。有关Tomcat配置的问题以及在开发和运行应用程序时遇到的问题通常更适合TOMCAT-USER列表。

并且,如果您认为某些内容应该在文档中,请务必在TOMCAT-DEV列表中告知我们。

 

设置 - 如何在各种平台上安装和运行Apache Tomcat。

有几种方法可以将Tomcat设置为在不同平台上运行。这方面的主要文档是一个名为RUNNING.txt的文件 。如果以下信息无法回答您的一些问题,我们建议您参考该文件。

Windows

使用Windows安装程序可以轻松地在Windows上安装Tomcat。它的界面和功能类似于其他基于向导的安装程序,只有少数感兴趣的项目。

  • 作为服务安装:无论选择何种设置,Tomcat都将作为Windows服务安装。使用组件页面上的复选框将服务设置为“自动”启动,以便在Windows启动时自动启动Tomcat。为获得最佳安全性,该服务应作为单独的用户运行,权限降低(请参阅Windows服务管理工具及其文档)。
  • Java位置:安装程序将提供用于运行服务的默认JRE。安装程序使用注册表来确定Java 8或更高版本JRE的基本路径,包括作为完整JDK的一部分安装的JRE。在64位操作系统上运行时,安装程​​序将首先查找64位JRE,如果未找到64位JRE,则仅查找32位JRE。使用安装程序检测到的默认JRE不是必需的。可以使用任何已安装的Java 8或更高版本的JRE(32位或64位)。
  • 托盘图标:当Tomcat作为服务运行时,Tomcat运行时不会出现任何托盘图标。请注意,在安装结束时选择运行Tomcat时,即使Tomcat作为服务安装,也将使用托盘图标。
  • 默认值:可以使用/C=<config file>命令行参数覆盖安装程序使用的默认值。配置文件name=value在单独的行上使用每对的格式 。可用配置选项的名称是:
    • 的JavaHome
    • TomcatPortShutdown
    • TomcatPortHttp
    • TomcatPortAjp
    • TomcatMenuEntriesEnable
    • TomcatShortcutAllUsers
    • TomcatServiceDefaultName
    • TomcatServiceName
    • TomcatServiceFileName
    • TomcatServiceManagerFileName
    • TomcatAdminEnable
    • TomcatAdminUsername
    • TomcatAdminPassword
    • TomcatAdminRoles
    通过/C=...一起使用/S, /D=可以执行Apache Tomcat的完全配置的无人参与安装。
  • 有关如何将Tomcat作为Windows服务进行管理的信息,请参阅 Windows Service HOW-TO

安装程序将创建允许启动和配置Tomcat的快捷方式。请务必注意,Tomcat管理Web应用程序只能在Tomcat运行时使用。

Unix守护进程

可以使用commons-daemon项目中的jsvc工具将Tomcat作为守护程序运行。jsvc的源代码压缩包包含在Tomcat二进制文件中,需要编译。构建jsvc需要C ANSI编译器(例如GCC),GNU Autoconf和JDK。

在运行脚本之前,JAVA_HOME应将环境变量设置为JDK的基本路径。或者,在调用./configure脚本时,可以使用--with-java参数指定JDK的路径,例如./configure --with-java=/usr/java

使用以下命令应该会生成位于该$CATALINA_HOME/bin文件夹中的已编译的jsvc二进制文件。这假设使用了GNU TAR,这CATALINA_HOME是一个指向Tomcat安装基本路径的环境变量。

请注意,您应该在FreeBSD系统上使用GNU make(gmake)而不是本机BSD make。

cd $CATALINA_HOME/bin
tar xvfz commons-daemon-native.tar.gz
cd commons-daemon-1.1.x-native-src/unix
./configure
make
cp jsvc ../..
cd ../..

然后可以使用以下命令将Tomcat作为守护程序运行。

CATALINA_BASE=$CATALINA_HOME
cd $CATALINA_HOME
./bin/jsvc \
    -classpath $CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/tomcat-juli.jar \
    -outfile $CATALINA_BASE/logs/catalina.out \
    -errfile $CATALINA_BASE/logs/catalina.err \
    -Dcatalina.home=$CATALINA_HOME \
    -Dcatalina.base=$CATALINA_BASE \
    -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
    -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \
    org.apache.catalina.startup.Bootstrap

在Java 9上运行时,您需要在启动jsvc时另外指定以下内容以避免在关闭时发出警告。

...
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED \
...

您可能还需要指定-jvm serverJVM是否默认使用服务器VM而不是客户端VM。这已在OSX上观察到。

jsvc还有其他有用的参数,例如-user在守护进程初始化完成后它会切换到另一个用户。例如,这允许将Tomcat作为非特权用户运行,同时仍然可以使用特权端口。请注意,如果您使用此选项并以root身份启动Tomcat,则需要禁用org.apache.catalina.security.SecurityListener以root身份运行时阻止Tomcat启动的 检查。

jsvc --help将返回完整的jsvc使用信息。特别是,该-debug选项对于调试运行jsvc的问题很有用。

该文件$CATALINA_HOME/bin/daemon.sh可用作模板,以便在启动时/etc/init.d使用jsvc 自动启动Tomcat 。

请注意,Commons-Daemon JAR文件必须位于运行时类路径上才能以这种方式运行Tomcat。Commons-Daemon JAR文件位于bootstrap.jar清单的Class-Path条目中,但如果您获得Commons-Daemon类的ClassNotFoundException或NoClassDefFoundError,则在启动jsvc时将Commons-Daemon JAR添加到-cp参数。

 

Tomcat Web应用程序部署

部署是用于将Web应用程序(第三方WAR或您自己的自定义Web应用程序)安装到Tomcat服务器的过程中的术语。

Web应用程序部署可以在Tomcat服务器中以多种方式完成。

  • 静态; 在Tomcat启动之前设置Web应用程序
  • 动态; 通过直接操作已部署的Web应用程序(依赖于自动部署 功能)或使用Tomcat Manager Web应用程序远程操作

Tomcat管理器是一个可以交互使用(通过HTML GUI)或以编程方式(通过基于URL的API)来部署和管理Web应用程序的Web应用程序。

有许多方法可以执行依赖Manager Web应用程序的部署。Apache Tomcat为Apache Ant构建工具提供任务。 Apache Tomcat Maven插件 项目提供与Apache Maven的集成。还有一个名为Client Deployer的工具,可以从命令行使用它,并提供其他功能,例如编译和验证Web应用程序以及将Web应用程序打包到Web应用程序资源(WAR)文件中。

安装

静态部署Web应用程序不需要安装,因为Tomcat提供了开箱即用的功能。尽管Tomcat Manager手册中详细说明了某些配置,但Tomcat Manager的部署功能也不需要任何安装 。但是,如果您希望使用Tomcat客户端部署程序(TCD),则需要安装。

TCD未与Tomcat核心发行版一起打包,因此必须从“下载”区域单独下载。下载通常标记为 apache-tomcat-9.0.x-deployer

TCD具有Apache Ant 1.6.2+和Java安装的先决条件。您的环境应定义指向Ant安装根目录的ANT_HOME环境值,以及指向Java安装的JAVA_HOME值。此外,您应该确保Ant的ant命令,并且Java javac编译器命令从您的操作系统提供的命令shell运行。

  1. 下载TCD发行版
  2. 不需要将TCD包提取到任何现有的Tomcat安装中,它可以被提取到任何位置。
  3. 阅读使用 Tomcat客户端部署程序

关于上下文的一个词

在谈论Web应用程序的部署时,需要理解Context的概念 。Context是Tomcat称之为Web应用程序的。

为了在Tomcat中配置Context, 需要一个Context Descriptor。上下文描述符只是一个XML文件,它包含上下文的Tomcat相关配置,例如命名资源或会话管理器配置。在早期版本的Tomcat中,Context Descriptor配置的内容通常存储在Tomcat的主配置文件server.xml中,但现在不建议这样做(尽管它目前仍然有效)。

上下文描述符不仅帮助Tomcat知道如何配置上下文,而且其他工具(如Tomcat Manager和TCD)通常使用这些上下文描述符来正确执行其角色。

上下文描述符的位置是:

  1. $ CATALINA_BASE/CONF/ [引擎] / [主机名] / [webappname] .XML
  2. $ CATALINA_BASE/webapps/目录[webappname] /META-INF/context.xml

(1)中的文件名为[webappname] .xml,但(2)中的文件名为context.xml。如果没有为Context提供Context Descriptor,Tomcat将使用默认值配置Context。

在Tomcat启动时部署

如果您对使用Tomcat Manager或TCD不感兴趣,那么您需要将Web应用程序静态部署到Tomcat,然后是Tomcat启动。您为此类部署部署Web应用程序的位置称为appBase每个主机指定的位置。您可以将所谓的展开的Web应用程序(即非压缩的)复制到此位置,或压缩的Web应用程序资源.WAR文件。

appBase仅当主机的deployOnStartup属性为“true”时,将在Tomcat启动时部署 由主机(默认主机为“localhost”)属性指定的位置中的Web应用程序(默认appBase为“$ CATALINA_BASE / webapps”)。

在这种情况下,Tomcat启动时将发生以下部署顺序:

  1. 将首先部署任何上下文描述符。
  2. 然后将部署未被任何上下文描述符引用的爆炸Web应用程序。如果他们在appBase中有一个关联的.WAR文件,并且它比爆炸的Web应用程序更新,则会删除展开的目录,并从.WAR重新部署webapp。
  3. 将部署.WAR文件

在正在运行的Tomcat服务器上部署

可以将Web应用程序部署到正在运行的Tomcat服务器。

如果Host autoDeploy属性为“true”,则Host将尝试根据需要动态部署和更新Web应用程序,例如,如果将新的.WAR放入其中appBase。为此,主机需要启用后台处理,这是默认配置。

autoDeploy 设置为“true”,运行Tomcat允许:

  • 部署.WAR文件复制到主机中appBase
  • 部署已复制到主机中的爆炸式Web应用程序appBase
  • 重新部署已在提供新.WAR时从.WAR部署的Web应用程序。在这种情况下,将删除爆炸的Web应用程序,并再次展开.WAR。请注意,如果配置主机以使.WAR未展开且unpackWARs 属性设置为“false”,则不会发生爆炸,在这种情况下,Web应用程序将简单地重新部署为压缩存档。
  • 如果更新了/WEB-INF/web.xml文件(或定义为WatchedResource的任何其他资源),则重新加载Web应用程序。
  • 如果更新了部署Web应用程序的Context Descriptor文件,则重新部署Web应用程序。
  • 如果更新Web应用程序使用的全局或每主机上下文描述符文件,则重新部署从属Web应用程序。
  • 如果将上下文描述符文件(具有与先前部署的Web应用程序的上下文路径对应的文件名)添加到$CATALINA_BASE/conf/[enginename]/[hostname]/ 目录中,则重新部署Web应用程序 。
  • 如果删除了其文档库(docBase),则取消部署Web应用程序。请注意,在Windows上,这假定启用了反锁定功能(请参阅上下文配置),否则无法删除正在运行的Web应用程序的资源。

请注意,也可以在加载程序中配置Web应用程序重新加载,在这种情况下,将跟踪已加载的类以进行更改。

使用Tomcat Manager进行部署

Tomcat Manager包含在自己的手册页中

使用客户端部署程序包进行部署

最后,可以使用Tomcat Client Deployer实现Web应用程序的部署。这是一个包,可用于验证,编译,压缩到.WAR,以及将Web应用程序部署到生产或开发Tomcat服务器。应该注意,此功能使用Tomcat Manager,因此目标Tomcat服务器应该运行。

假设用户熟悉Apache Ant以使用TCD。Apache Ant是一个脚本化的构建工具。TCD预先打包了要使用的构建脚本。只需要对Apache Ant有一定的了解(本页前面列出的安装,熟悉使用操作系统命令shell和配置环境变量)。

TCD包括Ant任务,部署前用于JSP编译的Jasper页面编译器,以及验证Web应用程序上下文描述符的任务。验证器任务(类org.apache.catalina.ant.ValidatorTask)仅允许一个参数:爆炸Web应用程序的基本路径。

TCD使用爆炸的Web应用程序作为输入(请参阅下面使用的属性列表)。以部署程序编程部署的Web应用程序可以包括上下文描述符 /META-INF/context.xml

TCD包含一个即用型Ant脚本,具有以下目标:

  • compile(默认):编译并验证Web应用程序。这可以单独使用,也不需要运行Tomcat服务器。已编译的应用程序将仅在关联的 Tomcat XYZ服务器版本上运行,并且无法保证在另一个Tomcat版本上运行,因为Jasper生成的代码取决于其运行时组件。还应注意,此目标还将自动编译位于/WEB-INF/classesWeb应用程序文件夹中的任何Java源文件 。
  • deploy:将Web应用程序(已编译或未编译)部署到Tomcat服务器。
  • undeploy:取消部署Web应用程序
  • start:启动Web应用程序
  • reload:重新加载Web应用程序
  • stop:停止Web应用程序

为了配置部署,请创建deployer.properties在TCD安装目录root中调用的文件。在此文件中,每行添加以下name = value对:此外,您需要确保已为目标Tomcat Manager(TCD使用)设置了用户,否则TCD将不会使用Tomcat Manager进行身份验证,部署将失败。要执行此操作,请参阅Tomcat Manager页面。

  • build:默认情况下,使用的构建文件夹 ${build}/webapp/${path}${build}默认情况下指向${basedir}/build)。在compile目标执行结束后,Web应用程序.WAR将位于 ${build}/webapp/${path}.war
  • webapp:包含将被编译和验证的爆炸Web应用程序的目录。默认情况下,该文件夹是 myapp
  • path:默认情况下,部署Web应用程序的上下文路径/myapp
  • url:正在运行的Tomcat服务器的Tomcat Manager Web应用程序的绝对URL,将用于部署和取消部署Web应用程序。默认情况下,部署者将尝试访问在localhost上运行的Tomcat实例 http://localhost:8080/manager/text
  • username:Tomcat Manager用户名(用户应该具有manager-script的角色)
  • password:Tomcat Manager密码。

 

在许多生产环境中,具有部署新Web应用程序或取消部署现有Web应用程序的功能非常有用,而无需关闭并重新启动整个容器。此外,即使您尚未将其声明为reloadable在Tomcat服务器配置文件中,也可以请求现有应用程序重新加载自身。

为了支持这些功能,Tomcat包括一个支持以下功能的Web应用程序(默认安装在上下文路径上/manager):

  • 从WAR文件的上载内容部署新的Web应用程序。
  • 从服务器文件系统在指定的上下文路径上部署新的Web应用程序。
  • 列出当前部署的Web应用程序,以及这些Web应用程序当前处于活动状态的会话。
  • 重新加载现有的Web应用程序,以反映/WEB-INF/classes或的内容更改/WEB-INF/lib
  • 列出OS和JVM属性值。
  • 列出可用的全局JNDI资源,以用于准备<ResourceLink>嵌套在<Context>部署描述中的元素的部署工具。
  • 启动已停止的应用程序(从而使其再次可用)。
  • 停止现有应用程序(以使其变得不可用),但不要取消部署它。
  • 取消部署已部署的Web应用程序并删除其文档基目录(除非它是从文件系统部署的)。

默认的Tomcat安装包括Manager。要将Manager Web应用程序的实例添加Context到新主机,请在manager.xml文件$CATALINA_BASE/conf/[enginename]/[hostname]夹中安装 上下文配置文件 。这是一个例子:

<Context privileged="true" antiResourceLocking="false"
         docBase="${catalina.home}/webapps/manager">
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.0\.0\.1" />
</Context>

如果您将Tomcat配置为支持多个虚拟主机(网站),则需要为每个虚拟主机配置一个Manager。

有三种方法可以使用Manager Web应用程序。

  • 作为具有用户界面的应用程序,您可以在浏览器中使用。以下是一个示例网址,您可以在其中替换localhost您的网站主机名:http://localhost:8080/manager/html
  • 仅使用HTTP请求的最小版本,适用于系统管理员设置的脚本。命令作为请求URI的一部分给出,响应采用简单文本的形式,可以很容易地进行解析和处理。有关更多信息,请参阅 支持的Manager命令
  • Ant (版本1.4或更高版本)构建工具的一组方便的任务定义。有关更多信息,请参阅 使用Ant执行Manager命令

配置Manager Application Access

下面的描述使用变量名$ CATALINA_BASE来引用解析大多数相对路径的基目录。如果尚未通过设置CATALINA_BASE目录为多个实例配置Tomcat,则$ CATALINA_BASE将设置为$ CATALINA_HOME的值,即已安装Tomcat的目录。

使用默认设置发送Tomcat是非常不安全的,这些设置允许Internet上的任何人在您的服务器上执行Manager应用程序。因此,Manager应用程序出厂时要求尝试使用它的任何人必须使用具有与之关联的manager-xxx角色之一的用户名和密码进行身份验证(角色名称取决于所需的功能)。此外,默认用户文件($CATALINA_BASE/conf/tomcat-users.xml)中没有分配给这些角色的用户名。因此,默认情况下完全禁用对Manager应用程序的访问。

您可以web.xml在Manager Web应用程序的文件中找到角色名称。可用的角色是:

  • manager-gui - 访问HTML界面。
  • manager-status - 仅访问“服务器状态”页面。
  • manager-script - 访问本文档中描述的工具友好的纯文本界面,以及“服务器状态”页面。
  • manager-jmx - 访问JMX代理接口和“服务器状态”页面。

HTML接口受到CSRF(跨站点请求伪造)攻击的保护,但文本和JMX接口无法受到保护。这意味着当使用Web浏览器访问Manager应用程序时,允许访问文本和JMX界面的用户必须小心谨慎。为了保持CSRF保护:

  • 如果使用Web浏览器使用具有manager-script或 manager-jmx角色的用户访问Manager应用程序(例如,用于测试纯文本或JMX接口),则必须先关闭浏览器的所有窗口以终止会话。如果您不关闭浏览器并访问其他站点,您可能会成为CSRF攻击的受害者。
  • 建议永远不要将manager-scriptmanager-jmx 角色授予具有manager-gui角色的用户。

注意,JMX代理接口实际上是Tomcat的低级根类管理接口。如果他知道要调用什么命令,那么可以做很多事情。启用manager-jmx角色时应该谨慎 。

要启用对Manager Web应用程序的访问,您必须创建新的用户名/密码组合并将其中一个manager-xxx角色与其关联 ,或者将manager-xxx角色添加 到某些现有用户名/密码组合中。由于本文档的大部分内容都描述了使用文本界面,因此本示例将使用角色名称管理器脚本。具体如何配置用户名/密码取决于 您使用的Realm实现

  • UserDatabaseRealm加上MemoryUserDatabaseMemoryRealm - UserDatabaseRealmMemoryUserDatabase是默认配置的$CATALINA_BASE/conf/server.xmlMemoryUserDatabaseMemoryRealm都默认读取存储在的XML格式文件 $CATALINA_BASE/conf/tomcat-users.xml,可以使用任何文本编辑器进行编辑。此文件包含<user>每个用户的XML ,可能如下所示:
    <user username="craigmcc" password="secret" roles="standard,manager-script" />
    它定义了此人用于登录的用户名和密码,以及与其关联的角色名称。您可以将manager-script角色添加到roles一个或多个现有用户的逗号分隔 属性,和/或使用该分配的角色创建新用户。
  • DataSourceRealmJDBCRealm - 您的用户和角色信息存储在通过JDBC访问的数据库中。根据环境的标准过程,将manager-script角色添加到一个或多个现有用户,和/或创建一个或多个已分配此角色的新用户。
  • JNDIRealm - 您的用户和角色信息存储在通过LDAP访问的目录服务器中。根据环境的标准过程,将manager-script角色添加 到一个或多个现有用户,和/或创建一个或多个已分配此角色的新用户。

第一次尝试发出下一节中描述的Manager命令之一时,您将面临使用BASIC身份验证登录的挑战。您输入的用户名和密码无关紧要,只要它们在用户数据库中标识拥有角色管理器脚本的有效用户即可。

除了密码限制之外,远程IP地址或主机可以通过添加RemoteAddrValve或来限制对Manager Web应用程序的访问RemoteHostValve。有关 详情,请参阅阀门文档 以下是通过IP地址限制对localhost的访问的示例:

<Context privileged="true">
         <Valve className="org.apache.catalina.valves.RemoteAddrValve"
                allow="127\.0\.0\.1"/>
</Context>

HTML用户友好界面

Manager Web应用程序的用户友好HTML界面位于

http://{host}:{port}/manager/html

如上所述,您需要manager-gui 角色才能访问它。有一个单独的文档,提供有关此接口的帮助。看到:

HTML接口受到CSRF(跨站点请求伪造)攻击的保护。每次访问HTML页面都会生成一个随机令牌,该令牌存储在您的会话中,并包含在页面上的所有链接中。如果您的下一个操作没有正确的令牌值,则该操作将被拒绝。如果令牌已过期,您可以从Manager的主页面或列表应用程序页面重新开始 。

支持的Manager命令

Manager应用程序知道如何处理的所有命令都在单个请求URI中指定,如下所示:

http://{host}:{port}/manager/text/{command}?{parameters}

where {host}{port}表示运行Tomcat的主机名和端口号,{command} 表示要执行的Manager命令,并 {parameters}表示特定于该命令的查询参数。在下面的插图中,根据您的安装自定义主机和端口。

这些命令通常由HTTP GET请求执行。该 /deploy命令具有由HTTP PUT请求执行的表单。

常用参数

大多数命令接受以下一个或多个查询参数:

  • path - 您正在处理的Web应用程序的上下文路径(包括前导斜杠)。要选择ROOT Web应用程序,请指定“/”。 
    注意:无法在Manager应用程序本身上执行管理命令。 
    注意:如果未明确指定path 参数,则将使用config参数中的标准Context命名规则或者如果config参数不存在而使用war参数派生路径和版本 。
  • version - 并行部署功能使用的此Web应用程序的版本。如果在需要路径的任何地方使用并行部署,则必须指定除路径之外的版本,并且路径和版本的组合必须是唯一的,而不仅仅是路径。 
    注意:如果未明确指定路径,则忽略version参数。
  • war - Web应用程序归档(WAR)文件的URL,或包含Web应用程序的目录的路径名,或Context配置“.xml”文件。您可以使用以下任何格式的网址:
    • file:/ absolute / path / to / a / directory - 包含Web应用程序的解压缩版本的目录的绝对路径。此目录将附加到您指定的上下文路径,而不进行任何更改。
    • file:/absolute/path/to/a/webapp.war - Web应用程序归档(WAR)文件的绝对路径。这是有效的 唯一/deploy命令,并且是于该命令的唯一可接受的格式。
    • file:/absolute/path/to/a/context.xml - Web应用程序的绝对路径上下文配置“.xml”文件,其中包含Context配置元素。
    • directory - 主机应用程序基目录中Web应用程序上下文的目录名称。
    • webapp.war - 位于主机应用程序基目录中的Web应用程序war文件的名称。

每个命令都将返回text/plain格式的响应(即没有HTML标记的纯ASCII),使人和程序都能轻松阅读)。响应的第一行将以OK或开头 FAIL,表示请求的命令是否成功。如果失败,第一行的其余部分将包含遇到的问题的描述。一些命令包括如下所述的附加信息行。

国际化注 - Manager应用程序在资源包中查找其消息字符串,因此可能已为您的平台翻译了字符串。以下示例显示了消息的英文版本。

远程部署新的应用程序存档(WAR)

http://localhost:8080/manager/text/deploy?path=/foo

上载在此HTTP PUT请求中指定为请求数据的Web应用程序归档(WAR)文件,将其安装到appBase 相应虚拟主机的目录中,然后启动,appBase从指定路径派生添加到WAR文件的WAR文件的名称。稍后可以使用该/undeploy命令取消部署应用程序(并删除相应的WAR文件)。

该命令由HTTP PUT请求执行。

.WAR文件可以包括Tomcat特定的部署配置,方法是在其中包含Context配置XML文件 /META-INF/context.xml

网址参数包括:

  • update:设置为true时,将首先取消部署任何现有更新。默认值设置为false。
  • tag:指定标记名称,这允许将部署的webapp与标记或标签相关联。如果取消部署Web应用程序,则可以在需要时仅使用标记重新部署它。
  • config :格式文件中的Context配置“.xml”文件的URL :/absolute/path/to/a/context.xml。这必须是Web应用程序上下文配置“.xml”文件的绝对路径,该文件包含Context配置元素。

 - 该命令与命令的逻辑相反/undeploy

如果安装和启动成功,您将收到如下响应:

OK - Deployed application at context path /foo

否则,响应将以FAIL错误消息开头并包含错误消息。可能的问题原因包括:

  • 应用程序已经存在于path / foo中

    所有当前运行的Web应用程序的上下文路径必须是唯一的。因此,您必须使用此上下文路径取消部署现有Web应用程序,或为新应用程序选择其他上下文路径。该update参数可以指定为URL上的参数,其值为true避免此错误。在这种情况下,将在执行部署之前对现有应用程序执行取消部署。

  • 遇到异常

    尝试启动新的Web应用程序时遇到异常。检查Tomcat日志以获取详细信息,但可能的解释包括解析/WEB-INF/web.xml文件时出现问题,或者在初始化应用程序事件侦听器和过滤器时遇到缺少的类。

从本地路径部署新应用程序

部署并启动附加到指定上下文的新Web应用程序 path(任何其他Web应用程序都不得使用该应用程序)。此命令与命令的逻辑相反/undeploy

此命令由HTTP GET请求执行。可以使用许多不同的方法来使用deploy命令。

部署以前部署的Web应用程序

http://localhost:8080/manager/text/deploy?path=/footoo&tag=footag

这可用于部署先前部署的Web应用程序,该应用程序已使用该tag属性进行部署。请注意,Manager webapp的工作目录将包含以前部署的WAR; 删除它会使部署失败。

按URL部署目录或WAR

部署位于Tomcat服务器上的Web应用程序目录或“.war”文件。如果未path指定,则路径和版本从目录名称或war文件名派生。该war参数指定file:目录或Web应用程序归档(WAR)文件的URL(包括方案)。引用WAR文件的URL支持的语法在java.net.JarURLConnection类的Javadocs页面上描述 。仅使用引用整个WAR文件的URL。

在此示例中,位于/path/to/fooTomcat服务器上的目录 中的Web应用程序将部署为名为的Web应用程序上下文/footoo

http://localhost:8080/manager/text/deploy?path=/footoo&war=file:/path/to/foo

在此示例中,/path/to/bar.warTomcat服务器上的“.war”文件被部署为名为的Web应用程序上下文 /bar。请注意,没有path参数,因此上下文路径默认为没有“.war”扩展名的Web应用程序归档文件的名称。

http://localhost:8080/manager/text/deploy?war=file:/path/to/bar.war

从主机appBase部署目录或战争

部署位于Host appBase目录中的Web应用程序目录或“.war”文件。路径和可选版本派生自目录或war文件名。

在此示例中,位于 fooTomcat服务器的Host appBase目录中指定的子目录中的Web应用程序被部署为名为的Web应用程序上下文/foo。请注意,使用的上下文路径是Web应用程序目录的名称。

http://localhost:8080/manager/text/deploy?war=foo

在此示例中,bar.war位于Tomcat服务器上的Host appBase目录中的“.war”文件被部署为名为的Web应用程序上下文/bar

http://localhost:8080/manager/text/deploy?war=bar.war

使用Context配置“.xml”文件进行部署

如果Host deployXML标志设置为true,则可以使用Context配置“.xml”文件和可选的“.war”文件或Web应用程序目录来部署Web应用程序。上下文path 使用上下文“.XML”配置文件部署Web应用程序时不被使用。

Context配置“.xml”文件可以包含Web应用程序的有效XML,就像它在Tomcat server.xml配置文件中配置一样。这是一个例子:

<Context path="/foobar" docBase="/path/to/application/foobar">
</Context>

当可选war参数设置为Web应用程序“.war”文件或目录的URL时,它将覆盖在上下文配置“.xml”文件中配置的任何docBase。

以下是使用Context配置“.xml”文件部署应用程序的示例。

http://localhost:8080/manager/text/deploy?config=file:/path/context.xml

以下是使用Context配置“.xml”文件和位于服务器上的Web应用程序“.war”文件部署应用程序的示例。

http://localhost:8080/manager/text/deploy
 ?config=file:/path/context.xml&war=file:/path/bar.war

部署说明

如果主机配置了unpackWARs = true并且您部署了war文件,则war将被解压缩到Host appBase目录中的目录中。

如果应用程序war或目录安装在Host appBase目录中,并且Host配置了autoDeploy = true,或者Context路径必须与没有“.war”扩展名的目录名或war文件名匹配。

为了在不受信任的用户可以管理Web应用程序时的安全性,可以将Host deployXML标志设置为false。这可以防止不受信任的用户使用配置XML文件部署Web应用程序,还可以防止他们部署位于其主机appBase之外的应用程序目录或“.war”文件。

部署响应

如果安装和启动成功,您将收到如下响应:

OK - Deployed application at context path /foo

否则,响应将以FAIL错误消息开头并包含错误消息。可能的问题原因包括:

  • 应用程序已经存在于path / foo中

    所有当前运行的Web应用程序的上下文路径必须是唯一的。因此,您必须使用此上下文路径取消部署现有Web应用程序,或为新应用程序选择其他上下文路径。该update参数可以指定为URL上的参数,其值为true避免此错误。在这种情况下,将在执行部署之前对现有应用程序执行取消部署。

  • 文档库不存在或不是可读目录

    war参数指定的URL 必须标识此服务器上包含Web应用程序的“解压缩”版本的目录,或包含此应用程序的Web应用程序归档(WAR)文件的绝对URL。更正war参数指定的值。

  • 遇到异常

    尝试启动新的Web应用程序时遇到异常。检查Tomcat日志以获取详细信息,但可能的解释包括解析/WEB-INF/web.xml文件时出现问题,或者在初始化应用程序事件侦听器和过滤器时遇到缺少的类。

  • 指定了无效的应用程序URL

    您指定的目录或Web应用程序的URL无效。此类URL必须以此开头file:,并且WAR文件的URL必须以“.war”结尾。

  • 指定了无效的上下文路径

    上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。

  • 上下文路径必须与目录或WAR文件名匹配:

    如果应用程序war或目录安装在Host appBase目录中,并且Host配置了autoDeploy = true,则Context路径必须与没有“.war”扩展名的目录名或war文件名匹配。

  • 只能安装Host Web应用程序目录中的Web应用程序

    如果Host deployXML标志设置为false,则尝试在Host appBase目录之外部署Web应用程序目录或“.war”文件时,将发生此错误。

列出当前部署的应用程序

http://localhost:8080/manager/text/list

列出所有当前部署的Web应用程序的上下文路径,当前状态(running或 stopped)和活动会话数。启动Tomcat后立即执行的典型响应可能如下所示:

OK - Listed applications for virtual host localhost
/webdav:running:0:webdav
/examples:running:0:examples
/manager:running:0:manager
/:running:0:ROOT
/test:running:0:test##2
/test:running:0:test##1

重新加载现有应用程序

http://localhost:8080/manager/text/reload?path=/examples

发信号通知现有应用程序关闭并重新加载。当Web应用程序上下文不可重新加载并且您在/WEB-INF/classes 目录中更新了类或属性文件或者在目录中添加或更新了jar文件 时,这非常有用/WEB-INF/lib

如果此命令成功,您将看到如下响应:

OK - Reloaded application at context path /examples

否则,响应将以FAIL错误消息开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试重新启动Web应用程序时遇到异常。检查Tomcat日志以获取详细信息。

  • 指定了无效的上下文路径

    上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。

  • path / foo没有上下文

    您指定的上下文路径上没有已部署的应用程序。

  • 未指定上下文路径

    path参数是必需的。

  • 在路径/ foo上部署的WAR不支持重新加载

    当前,web.xml直接从WAR文件部署Web应用程序时,不支持应用程序重新加载(以获取对类或文件的更改 )。它仅在从解压缩目录部署Web应用程序时才有效。如果你使用的是WAR文件,你应该undeploydeploy或者 deployupdate参数应用程序再次拿起您的更改。

列出OS和JVM属性

http://localhost:8080/manager/text/serverinfo

列出有关Tomcat版本,操作系统和JVM属性的信息。

如果发生错误,响应将以FAIL包含错误消息的方式开始并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试枚举系统属性时遇到异常。检查Tomcat日志以获取详细信息。

列出可用的全局JNDI资源

http://localhost:8080/manager/text/resources[?type=xxxxx]

列出可在上下文配置文件的资源链接中使用的全局JNDI资源。如果指定type request参数,则该值必须是您感兴趣的资源类型的完全限定Java类名称(例如,您将指定 javax.sql.DataSource获取所有可用JDBC数据源的名称)。如果未指定typerequest参数,则将返回所有类型的资源。

根据是否type指定了请求参数,正常响应的第一行将是:

OK - Listed global resources of all types

要么

OK - Listed global resources of type xxxxx

每个资源后跟一行。每行由冒号字符(“:”)分隔的字段组成,如下所示:

  • 全局资源名称 - 此全局JNDI资源的名称,将在元素的global属性中使用 <ResourceLink>
  • 全局资源类型 - 此全局JNDI资源的完全限定Java类名。

如果发生错误,响应将以FAIL包含错误消息的方式开始并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试枚举全局JNDI资源时遇到异常。检查Tomcat日志以获取详细信息。

  • 没有可用的全局JNDI资源

    您运行的Tomcat服务器已配置为没有全局JNDI资源。

会话统计

http://localhost:8080/manager/text/sessions?path=/examples

显示Web应用程序的默认会话超时,以及在实际超时时间的一分钟范围内的当前活动会话数。例如,在重新启动Tomcat然后在/examplesWeb应用程序中执行其中一个JSP示例后,您可能会得到以下内容:

OK - Session information for application at context path /examples
Default maximum session inactive interval 30 minutes
<1 minutes: 1 sessions
1 - <2 minutes: 1 sessions

过期会话

http://localhost:8080/manager/text/expire?path=/examples&idle=num

显示会话统计信息(如上面的/sessions 命令),并使空闲时间超过num 分钟的会话失效。要使所有会话到期,请使用&idle=0

OK - Session information for application at context path /examples
Default maximum session inactive interval 30 minutes
1 - <2 minutes: 1 sessions
3 - <4 minutes: 1 sessions
>0 minutes: 2 sessions were expired

实际上/sessions并且/expire是同一命令的同义词。不同之处在于存在idle 参数。

启动现有应用程序

http://localhost:8080/manager/text/start?path=/examples

发出停止的应用程序信号以重新启动,并使其自身再次可用 例如,如果应用程序所需的数据库暂时不可用,则停止和启动很有用。通常最好停止依赖此数据库的Web应用程序,而不是让用户不断遇到数据库异常。

如果此命令成功,您将看到如下响应:

OK - Started application at context path /examples

否则,响应将以FAIL错误消息开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试启动Web应用程序时遇到异常。检查Tomcat日志以获取详细信息。

  • 指定了无效的上下文路径

    上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。

  • path / foo没有上下文

    您指定的上下文路径上没有已部署的应用程序。

  • 未指定上下文路径

    path参数是必需的。

停止现有的应用程序

http://localhost:8080/manager/text/stop?path=/examples

发信号通知现有应用程序使其自身不可用,但将其部署。应用程序停止时进入的任何请求都将看到HTTP错误404,此应用程序将在列表应用程序命令中显示为“已停止”。

如果此命令成功,您将看到如下响应:

OK - Stopped application at context path /examples

否则,响应将以FAIL错误消息开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试停止Web应用程序时遇到异常。检查Tomcat日志以获取详细信息。

  • 指定了无效的上下文路径

    上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。

  • path / foo没有上下文

    您指定的上下文路径上没有已部署的应用程序。

  • 未指定上下文路径 该path参数是必需的。

取消部署现有应用程序

http://localhost:8080/manager/text/undeploy?path=/examples

警告 - 此命令将删除appBase此虚拟主机的目录(通常为“webapps”)中存在的所有Web应用程序工件。这将删除应用程序.WAR(如果存在),应用程序目录来自解压缩形式的部署或.WAR扩展以及$CATALINA_BASE/conf/[enginename]/[hostname]/目录中的XML上下文定义 。如果您只是想让应用程序停止服务,则应该使用该/stop命令。

发信号通知现有应用程序正常关闭自身,并将其从Tomcat中删除(这也使得此上下文路径可供以后重用)。此外,如果文档根目录存在appBase于此虚拟主机的目录(通常为“webapps”)中,则将其删除。此命令与命令的逻辑相反 /deploy

如果此命令成功,您将看到如下响应:

OK - Undeployed application at context path /examples

否则,响应将以FAIL错误消息开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试取消部署Web应用程序时遇到异常。检查Tomcat日志以获取详细信息。

  • 指定了无效的上下文路径

    上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。

  • 没有名为/ foo的上下文

    没有已指定名称的已部署应用程序。

  • 未指定上下文路径 该path参数是必需的。

发现内存泄漏

http://localhost:8080/manager/text/findleaks[?statusLine=[true|false]]

查找泄漏诊断会触发完整的垃圾回收。它应该在生产系统中极其谨慎地使用。

查找泄漏诊断尝试识别在停止,重新加载或取消部署时导致内存泄漏的Web应用程序。应始终使用分析器确认结果。诊断使用StandardHost实现提供的其他功能。如果使用不扩展StandardHost的自定义主机,它将无法工作。

从Java代码中明确触发完整的垃圾收集被记录为不可靠。此外,根据所使用的JVM,还有禁用显式GC触发的选项,例如-XX:+DisableExplicitGC。如果要确保诊断程序成功运行完整的GC,则需要使用GC日志记录,JConsole或类似工具进行检查。

如果此命令成功,您将看到如下响应:

/leaking-webapp

如果您希望在响应中看到状态行,则statusLine在请求中包含 查询参数,其值为 true

已停止,重新加载或取消部署的Web应用程序的每个上下文路径,但先前运行的哪些类仍然加载到内存中,从而导致内存泄漏,将在新行上列出。如果应用程序已多次重新加载,则可能会多次列出。

如果命令不成功,则响应将以FAIL并包含错误消息开头 。

连接器SSL / TLS密码信息

http://localhost:8080/manager/text/sslConnectorCiphers

SSL Connector / Ciphers诊断列出了当前为每个连接器配置的SSL / TLS密码。对于NIO和NIO2,列出了各个密码套件的名称。对于APR,返回SSLCipherSuite的值。

响应将如下所示:

OK - Connector / SSL Cipher information
Connector[HTTP/1.1-8080]
  SSL is not enabled for this connector
Connector[HTTP/1.1-8443]
  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
  TLS_DHE_RSA_WITH_AES_128_CBC_SHA
  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
  ...

连接器SSL / TLS证书链信息

http://localhost:8080/manager/text/sslConnectorCerts

SSL Connector / Certs诊断列出了当前为每个虚拟主机配置的证书链。

响应将如下所示:

OK - Connector / Certificate Chain information
Connector[HTTP/1.1-8080]
SSL is not enabled for this connector
Connector[HTTP/1.1-8443]-_default_-RSA
[
[
  Version: V3
  Subject: CN=localhost, OU=Apache Tomcat PMC, O=The Apache Software Foundation, L=Wakefield, ST=MA, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
  ...

连接器SSL / TLS可信证书信息

http://localhost:8080/manager/text/sslConnectorTrustedCerts

SSL Connector / Certs诊断列出了当前为每个虚拟主机配置的可信证书。

响应将如下所示:

OK - Connector / Trusted Certificate information
Connector[HTTP/1.1-8080]
SSL is not enabled for this connector
Connector[AJP/1.3-8009]
SSL is not enabled for this connector
Connector[HTTP/1.1-8443]-_default_
[
[
  Version: V3
  Subject: CN=Apache Tomcat Test CA, OU=Apache Tomcat PMC, O=The Apache Software Foundation, L=Wakefield, ST=MA, C=US
  ...

重新加载TLS配置

http://localhost:8080/manager/text/sslReload?tlsHostName=name

重新加载TLS配置文件(证书和密钥文件,这不会触发重新解析server.xml)。要为所有主机重新加载文件,请不要指定tlsHostName参数。

OK - Reloaded TLS configuration for [_default_]

线程转储

http://localhost:8080/manager/text/threaddump

编写JVM线程转储。

响应将如下所示:

OK - JVM thread dump
2014-12-08 07:24:40.080
Full thread dump Java HotSpot(TM) Client VM (25.25-b02 mixed mode):

"http-nio-8080-exec-2" Id=26 cpu=46800300 ns usr=46800300 ns blocked 0 for -1 ms waited 0 for -1 ms
   java.lang.Thread.State: RUNNABLE
        locks java.util.concurrent.ThreadPoolExecutor$Worker@1738ad4
        at sun.management.ThreadImpl.dumpThreads0(Native Method)
        at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:446)
        at org.apache.tomcat.util.Diagnostics.getThreadDump(Diagnostics.java:440)
        at org.apache.tomcat.util.Diagnostics.getThreadDump(Diagnostics.java:409)
        at org.apache.catalina.manager.ManagerServlet.threadDump(ManagerServlet.java:557)
        at org.apache.catalina.manager.ManagerServlet.doGet(ManagerServlet.java:371)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
...

VM信息

http://localhost:8080/manager/text/vminfo

编写有关Java虚拟机的一些诊断信息。

响应将如下所示:

OK - VM info
2014-12-08 07:27:32.578
Runtime information:
  vmName: Java HotSpot(TM) Client VM
  vmVersion: 25.25-b02
  vmVendor: Oracle Corporation
  specName: Java Virtual Machine Specification
  specVersion: 1.8
  specVendor: Oracle Corporation
  managementSpecVersion: 1.2
  name: ...
  startTime: 1418012458849
  uptime: 393855
  isBootClassPathSupported: true

OS information:
...

保存配置

http://localhost:8080/manager/text/save

如果指定不带任何参数,则此命令将服务器的当前配置保存到server.xml。如果需要,现有文件将重命名为备份。

如果使用与已path部署的Web应用程序的路径匹配的参数进行指定,则该Web应用程序的配置将保存到xmlBase 当前主机的适当命名的context.xml文件中。

要使用该命令,必须存在StoreConfig MBean。通常,这是使用StoreConfigLifecycleListener配置的。

如果命令不成功,则响应将以FAIL并包含错误消息开头 。

服务器状态

从以下链接中,您可以查看有关服务器的状态信息。manager-xxx角色中的任何一个都允许访问此页面。

http://localhost:8080/manager/status
http://localhost:8080/manager/status/all

以HTML格式显示服务器状态信息。

http://localhost:8080/manager/status?XML=true
http://localhost:8080/manager/status/all?XML=true

以XML格式显示服务器状态信息。

首先,您拥有服务器和JVM版本号,JVM提供程序,操作系统名称和编号,后跟体系结构类型。

其次,有关于JVM的内存使用情况的信息。

然后,有关于Tomcat AJP和HTTP连接器的信息。两者都有相同的信息:

  • 线程信息:最大线程数,最小和最大备用线程数,当前线程数和当前线程忙数。

  • 请求信息:最大处理时间和处理时间,请求和错误计数,接收和发送的字节数。

  • 显示阶段,时间,发送字节,字节接收,客户端,VHost和请求的表。表中列出了所有现有线程。以下是可能的线程阶段列表:

    • “解析和准备请求”:正在解析请求标头或正在进行读取请求主体(如果已指定传输编码)的必要准备。

    • “服务”:线程正在处理请求并生成响应。此阶段遵循“解析和准备请求”阶段,并在“完成”阶段之前。此阶段始终至少有一个线程(服务器状态页面)。

    • “整理”:请求处理结束。仍在输出缓冲区中的任何剩余响应都将发送到客户端。如果适当地保持连接活动,则此阶段之后是“保持活动”,如果“保持活动”不合适,则“准备好”。

    • “Keep-Alive”:如果客户端发送另一个请求,则线程会保持对客户端的连接打开。如果收到另一个请求,则下一阶段将是“解析和准备请求”。如果在保持活动超时之前没有收到请求,则连接将关闭,下一阶段将为“就绪”。

    • “就绪”:线程处于静止状态并准备好使用。

如果您使用/status/all命令,则可以使用有关每个已部署Web应用程序的其他信息。

使用JMX代理Servlet

什么是JMX代理Servlet

JMX代理Servlet是一个轻量级代理,用于获取和设置tomcat内部。(或者通过MBean公开的任何类)它的用法不是非常用户友好,但UI对于集成命令行脚本以监视和更改tomcat的内部非常有用。您可以使用代理执行两项操作:获取信息和设置信息。为了让您真正了解JMX代理Servlet,您应该对JMX有一个大致的了解。如果您不知道JMX是什么,那么请准备好混淆。

JMX Query命令

采取以下形式:

http://webserver/manager/jmxproxy/?qry=STUFF

STUFF您希望执行的JMX查询在哪里。例如,以下是您可能希望运行的一些查询:

  • qry=*%3Atype%3DRequestProcessor%2C* --> type=RequestProcessor 它将找到可以处理请求并报告其状态的所有工作人员。
  • qry=*%3Aj2eeType=Servlet%2c* --> j2eeType=Servlet 返回所有加载的servlet。
  • qry=Catalina%3Atype%3DEnvironment%2Cresourcetype%3DGlobal%2Cname%3DsimpleValue --> Catalina:type=Environment,resourcetype=Global,name=simpleValue 它按给定名称查找特定MBean。

您需要对此进行实验以真正了解其功能如果您不提供qry参数,那么将显示所有MBean。我们真的建议查看tomcat源代码并理解JMX规范,以便更好地理解您可能运行的所有查询。

JMX获取命令

JXMProxyServlet还支持“get”命令,您可以使用该命令获取特定MBean属性的值。该get命令的一般形式是:

http://webserver/manager/jmxproxy/?get=BEANNAME&att=MYATTRIBUTE&key=MYKEY

您必须提供以下参数:

  1. get:完整的bean名称
  2. att:您要获取的属性
  3. key:(可选)CompositeData MBean属性的键

如果一切顺利,那么它会说OK,否则将显示错误消息。例如,假设我们希望获取当前堆内存数据:

http://webserver/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage

或者,如果您只想要“使用”密钥:

http://webserver/manager/jmxproxy/
 ?get=java.lang:type=Memory&att=HeapMemoryUsage&key=used

JMX Set命令

现在你可以查询一个MBean,它是时候去挖掘Tomcat的内部了!set命令的一般形式是:

http://webserver/manager/jmxproxy/?set=BEANNAME&att=MYATTRIBUTE&val=NEWVALUE

所以你需要提供3个请求参数:

  1. set:完整的bean名称
  2. att:您要更改的属性
  3. val:新的价值

如果一切正常,那么它会说OK,否则将显示错误消息。例如,假设我们希望立即启动调试 ErrorReportValve。以下将调试设置为10。

http://localhost:8080/manager/jmxproxy/
 ?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
 &att=debug&val=10

我的结果是(YMMV):

Result: ok

如果我传入一个错误的值,这就是我所看到的。这是我使用的URL,我尝试设置调试等于'cow':

http://localhost:8080/manager/jmxproxy/
 ?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
 &att=debug&val=cow

当我尝试时,我的结果是

Error: java.lang.NumberFormatException: For input string: "cow"

JMX Invoke命令

invoke命令允许在MBean上调用方法。该命令的一般形式是:

http://webserver/manager/jmxproxy/
 ?invoke=BEANNAME&op=METHODNAME&ps=COMMASEPARATEDPARAMETERS

例如,要调用Service使用的findConnectors()方法 :

http://localhost:8080/manager/jmxproxy/
 ?invoke=Catalina%3Atype%3DService&op=findConnectors&ps=

使用Ant执行Manager命令

除了通过HTTP请求执行Manager命令的能力之外,如上所述,Tomcat还包含一组方便的Ant(版本1.4或更高版本)构建工具的任务定义。要使用这些命令,必须执行以下设置操作:

  • https://ant.apache.org下载Ant的二进制发行版 。您必须使用1.4或更高版本。
  • 将Ant分发安装在方便的目录中(在这些说明的其余部分中称为ANT_HOME)。
  • $ANT_HOME/bin目录添加到PATH 环境变量中。
  • 在Tomcat用户数据库中至少配置一个包含该manager-script角色的用户名/密码组合。

要在Ant中使用自定义任务,必须先使用<import>元素声明它们 。因此,您的build.xml 文件可能如下所示:

<project name="My Application" default="compile" basedir=".">

  <!-- Configure the directory into which the web application is built -->
  <property name="build"    value="${basedir}/build"/>

  <!-- Configure the context path for this application -->
  <property name="path"     value="/myapp"/>

  <!-- Configure properties to access the Manager application -->
  <property name="url"      value="http://localhost:8080/manager/text"/>
  <property name="username" value="myusername"/>
  <property name="password" value="mypassword"/>

  <!-- Configure the path to the Tomcat installation -->
  <property name="catalina.home" value="/usr/local/apache-tomcat"/>

  <!-- Configure the custom Ant tasks for the Manager application -->
  <import file="${catalina.home}/bin/catalina-tasks.xml"/>

  <!-- Executable Targets -->
  <target name="compile" description="Compile web application">
    <!-- ... construct web application in ${build} subdirectory, and
            generated a ${path}.war ... -->
  </target>

  <target name="deploy" description="Install web application"
          depends="compile">
    <deploy url="${url}" username="${username}" password="${password}"
            path="${path}" war="file:${build}${path}.war"/>
  </target>

  <target name="reload" description="Reload web application"
          depends="compile">
    <reload  url="${url}" username="${username}" password="${password}"
            path="${path}"/>
  </target>

  <target name="undeploy" description="Remove web application">
    <undeploy url="${url}" username="${username}" password="${password}"
            path="${path}"/>
  </target>

</project>

注意:通过上面的导入定义资源任务将覆盖Ant 1.7中添加的资源数据类型。如果您希望使用资源数据类型,则需要使用Ant的命名空间支持进行修改, catalina-tasks.xml以将Tomcat任务分配给它们自己的命名空间。

现在,您可以执行命令,例如ant deploy将应用程序部署到正在运行的Tomcat实例,或者ant reload告诉Tomcat重新加载它。另请注意,此build.xml文件中的大多数有趣值都定义为可替换属性,因此您可以从命令行覆盖它们的值。例如,您可能认为在build.xml文件的源代码中包含真实管理员密码存在安全风险 。要避免这种情况,请省略password属性,并从命令行指定它:

ant -Dpassword=secret deploy

任务输出捕获

使用Ant版本1.6.2或更高版本,Catalina任务提供了在属性或外部文件中捕获其输出的选项。它们直接支持以下<redirector>类型属性的子集 :

属性描述需要
产量要写入输出的文件的名称。如果错误流也未重定向到文件或属性,则它将显示在此输出中。没有
错误应重定向命令标准错误的文件。没有
LOGERROR当您希望在Ant的日志中看到错误输出并且您将输出重定向到文件/属性时,将使用此属性。错误输出将不包含在输出文件/属性中。如果使用errorerrorProperty 属性重定向错误,则无效。没有
附加是否应附加或覆盖输出和错误文件。默认为false没有
createemptyfiles是否应该创建输出和错误文件,即使是空的。默认为true没有
outputproperty应存储命令输出的属性的名称。除非将错误流重定向到单独的文件或流,否则此属性将包含错误输出。没有
errorproperty应存储命令标准错误的属性的名称。没有

还可以指定一些其他属性:

属性描述需要
alwaysLog当您希望查看正在捕获的输出时,将使用此属性,该属性也显示在Ant的日志中。除非您正在捕获任务输出,否则不得使用它。默认为false。 Ant 1.6.3 将直接支持该属性<redirector>没有
failonerror当您希望避免任何管理器命令处理错误终止ant执行时,将使用此属性。默认为true。必须设置为false,如果要捕获错误输出,否则执行将在捕获任何内容之前终止。 
此属性仅作用于管理器命令执行,任何错误或缺少的命令属性仍将导致Ant执行终止。
没有

它们还支持嵌入<redirector>在其中您可以指定其完整的属性集元素,但是inputinputstring并且 inputencoding,即使接受,不使用,因为他们在这方面没有任何意义。有关元素属性的详细信息, 请参阅ant手册<redirector>

下面是一个示例构建文件摘录,显示了如何使用此输出重定向支持:

    <target name="manager.deploy"
        depends="context.status"
        if="context.notInstalled">
        <deploy url="${mgr.url}"
            username="${mgr.username}"
            password="${mgr.password}"
            path="${mgr.context.path}"
            config="${mgr.context.descriptor}"/>
    </target>

    <target name="manager.deploy.war"
        depends="context.status"
        if="context.deployable">
        <deploy url="${mgr.url}"
            username="${mgr.username}"
            password="${mgr.password}"
            update="${mgr.update}"
            path="${mgr.context.path}"
            war="${mgr.war.file}"/>
    </target>

    <target name="context.status">
        <property name="running" value="${mgr.context.path}:running"/>
        <property name="stopped" value="${mgr.context.path}:stopped"/>

        <list url="${mgr.url}"
            outputproperty="ctx.status"
            username="${mgr.username}"
            password="${mgr.password}">
        </list>

        <condition property="context.running">
            <contains string="${ctx.status}" substring="${running}"/>
        </condition>
        <condition property="context.stopped">
            <contains string="${ctx.status}" substring="${stopped}"/>
        </condition>
        <condition property="context.notInstalled">
            <and>
                <isfalse value="${context.running}"/>
                <isfalse value="${context.stopped}"/>
            </and>
        </condition>
        <condition property="context.deployable">
            <or>
                <istrue value="${context.notInstalled}"/>
                <and>
                    <istrue value="${context.running}"/>
                    <istrue value="${mgr.update}"/>
                </and>
                <and>
                    <istrue value="${context.stopped}"/>
                    <istrue value="${mgr.update}"/>
                </and>
            </or>
        </condition>
        <condition property="context.undeployable">
            <or>
                <istrue value="${context.running}"/>
                <istrue value="${context.stopped}"/>
            </or>
        </condition>
    </target>

警告:即使它没有多大意义,并且总是一个坏主意,不止一次调用Catalina任务,严重设置Ant任务取决于链可能导致在同一个Ant运行中多次调用任务,甚至如果不打算。当您从该任务捕获输出时,应该谨慎行事,因为这可能会导致意外情况:

  • 在属性中捕获时,您将在其中仅找到第一次调用的输出,因为Ant属性是不可变的,一旦设置它们就无法更改,
  • 在文件中捕获时,每次运行都会覆盖它,除非您使用该属性,否则您将在其中找到最后一次调用输出append="true",在这种情况下,您将看到附加到文件的每个任务调用的输出。

 

Host Manager应用程序 - 文本界面

Tomcat的主机管理应用程序,您可以创建,删除,否则在Tomcat管理虚拟主机。本操作指南最好附有以下文档:

Tomcat的主机管理应用程序是Tomcat安装的一部分,默认情况下可以通过如下的背景:/host-manager。您可以通过以下方式使用主机管理器:

  • 利用图形用户界面,可访问: {server}:{port}/host-manager/html
  • 利用一组适合脚本编写的最小HTTP请求。您可以访问此模式: {server}:{port}/host-manager/text

这两种方式都允许您添加,删除,启动和停止虚拟主机。可以使用该persist命令预先进行更改。本文档重点介绍文本界面。有关图形界面的更多信息,请参阅 Host Manager App - HTML界面

配置Manager Application Access

以下描述$CATALINA_HOME用于引用基本Tomcat目录。例如C:/tomcat9,它是您安装Tomcat的目录,或 /usr/share/tomcat9

Host Manager应用程序要求用户具有以下角色之一:

  • admin-gui - 将此角色用于图形Web界面。
  • admin-script - 将此角色用于脚本Web界面。

要启用对Host Manager应用程序的文本界面的访问,请为Tomcat用户授予适当的角色,或者创建具有正确角色的新角色。例如,打开${CATALINA_BASE}/conf/tomcat-users.xml并输入以下内容:

<user username="test" password="chang3m3N#w" roles="admin-script"/>

无需进一步设置。现在访问时 {server}:{port}/host-manager/text/${COMMAND},您可以使用创建的凭据登录。例如:

$ curl -u ${USERNAME}:${PASSWORD} http://localhost:8080/host-manager/text/list
OK - Listed hosts
localhost:

请注意,如果使用,或 机制检索用户 DataSourceRealm,请分别在数据库或目录服务器中添加适当的角色。 JDBCRealmJNDIRealm

命令列表

支持以下命令:

  • 名单
  • 去掉
  • 开始
  • 坚持

在以下小节中,假定用户名和密码为 test:test。对于您的环境,请使用前面部分中创建的凭据。

列表命令

使用list命令查看Tomcat实例上的可用虚拟主机。

示例命令

curl -u test:test http://localhost:8080/host-manager/text/list

响应示例

OK - Listed hosts
localhost:

添加命令

使用add命令添加新的虚拟主机。用于add命令的参数:

  • 字符串名称:虚拟主机的名称。需要
  • 字符串别名:虚拟主机的别名。
  • String appBase:此虚拟主机将提供的应用程序的基本路径。提供相对或绝对路径。
  • 布尔管理器:如果为true,则将Manager应用程序添加到虚拟主机。您可以使用/ manager上下文访问它。
  • Boolean autoDeploy:如果为true,Tomcat会自动重新部署appBase目录中的应用程序。
  • Boolean deployOnStartup:如果为true,则Tomcat会在启动时自动部署appBase目录中的应用程序。
  • Boolean deployXML:如果为true,则 Tomcat将读取并使用/META-INF/context.xml文件。
  • Boolean copyXML:如果为true,则Tomcat会复制/META-INF/context.xml 文件并使用原始副本,而不管应用程序的/META-INF/context.xml文件的更新如何 。

示例命令

curl -u test:test http://localhost:8080/host-manager/text/add?name=www.awesomeserver.com&aliases=awesomeserver.com&appBase/mnt/appDir&deployOnStartup=true

响应示例

add: Adding host [www.awesomeserver.com]

删除命令

使用remove命令删除虚拟主机。用于remove命令的参数:

  • 字符串名称:要删除的虚拟主机的名称。 需要

示例命令

curl -u test:test http://localhost:8080/host-manager/text/remove?name=www.awesomeserver.com

响应示例

remove: Removing host [www.awesomeserver.com]

启动命令

使用start命令启动虚拟主机。用于启动命令的参数:

  • 字符串名称:要启动的虚拟主机的名称。 需要

示例命令

curl -u test:test http://localhost:8080/host-manager/text/start?name=www.awesomeserver.com

响应示例

OK - Host www.awesomeserver.com started

停止命令

使用stop命令停止虚拟主机。用于stop命令的参数:

  • 字符串名称:要停止的虚拟主机的名称。 需要

示例命令

curl -u test:test http://localhost:8080/host-manager/text/stop?name=www.awesomeserver.com

响应示例

OK - Host www.awesomeserver.com stopped

坚持命令

使用persist命令将虚拟主机持久保存到 server.xml中。用于persist命令的参数:

  • 字符串名称:要保留的虚拟主机的名称。 需要

默认情况下禁用此功能。要启用此选项,必须首先配置StoreConfigLifecycleListener侦听器。为此,请将以下侦听器添加到server.xml

<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>

示例命令

curl -u test:test http://localhost:8080/host-manager/text/persist?name=www.awesomeserver.com

响应示例

OK - Configuration persisted

手动输入示例

<Host appBase="www.awesomeserver.com" name="www.awesomeserver.com" deployXML="false" unpackWARs="false">
</Host>

 

 

本文档介绍如何通过连接到用户名,密码和用户角色的现有“数据库” 来配置Tomcat以支持容器管理的安全性。如果您使用的是包含一个或多个<security-constraint>元素的Web应用程序,以及<login-config>定义用户如何验证自身身份的元素, 则只需要关注此问题 。如果您不使用这些功能,则可以安全地跳过本文档。

有关容器管理安全性的基本背景信息,请参阅Servlet规范(版本2.4),第12节。

有关利用Tomcat 的单点登录功能(允许用户在与虚拟主机关联的整个Web应用程序集中进行一次身份验证)的信息,请参阅 此处

概观

什么是领域?

一个领域是一个用户名和标识Web应用程序的有效用户(或一组Web应用程序)的密码“数据库”,加上名单的枚举角色与每个有效用户相关联。你可以把角色相似的群体在类Unix的操作系统,因为访问特定的Web应用程序资源被授予具有特定角色(而不是列举相关的用户名的列表)的所有用户。特定用户可以拥有与其用户名相关联的任意数量的角色。

尽管Servlet规范描述了应用程序声明其安全性要求的可移植机制(在 web.xml部署描述符中),但是没有可定义servlet容器与关联用户和角色信息之间的接口的可移植API。但是,在许多情况下,需要将servlet容器“连接”到生产环境中已存在的某些现有认证数据库或机制。因此,Tomcat定义了一个Java接口(org.apache.catalina.Realm),可以通过“插件”组件来实现,以建立此连接。提供了六个标准插件,支持与各种身份验证信息源的连接:

  • JDBCRealm - 访问存储在关系数据库中的身份验证信息,通过JDBC驱动程序访问。
  • DataSourceRealm - 访问存储在关系数据库中的身份验证信息,通过命名的JNDI JDBC DataSource访问。
  • JNDIRealm - 访问存储在基于LDAP的目录服务器中的身份验证信息,通过JNDI提供程序访问。
  • UserDatabaseRealm - 访问存储在UserDatabase JNDI资源中的身份验证信息,该资源通常由XML文档(conf/tomcat-users.xml)支持。
  • MemoryRealm - 访问存储在内存中对象集合中的身份验证信息,该集合是从XML文档(conf/tomcat-users.xml)初始化的。
  • JAASRealm - 通过Java身份验证和授权服务(JAAS)框架访问身份验证信息。

也可以编写自己的Realm实现,并将其与Tomcat集成。为此,您需要:

  • 实施org.apache.catalina.Realm
  • 将编译的域放在$ CATALINA_HOME / lib中,
  • 按照下面“配置领域”部分所述声明您的领域,
  • MBeans描述符声明您的领域。

配置领域

在深入了解标准Realm实现的细节之前,一般来说,了解Realm的配置方式非常重要。通常,您将在conf/server.xml 配置文件中添加一个XML元素,如下所示:

<Realm className="... class name for this implementation"
       ... other attributes for this implementation .../>

<Realm>元素可以嵌套在以下任何一个Container元素中。Realm元素的位置直接影响该Realm的“范围”(即哪些Web应用程序将共享相同的身份验证信息):

  • 在<Engine>元素内部 - 此Realm将在所有虚拟主机上的所有Web应用程序之间共享,除非它被嵌套在从属<Host> 或<Context>元素中的Realm元素覆盖。
  • 在<Host>元素内部 - 此Realm将在此虚拟主机的所有Web应用程序之间共享,除非它被嵌套在从属<Context> 元素中的Realm元素覆盖。
  • 在<Context>元素内 - 此Realm将仅用于此Web应用程序。

共同特征

消化密码

对于每个标准Realm实现,用户的密码(默认情况下)以明文形式存储。在许多环境中,这是不合需要的,因为认证数据的临时观察者可以收集足够的信息以成功登录,并冒充其他用户。为避免此问题,标准实现支持消化 用户密码的概念。这允许对存储的密码版本进行编码(以不易翻转的形式),但 Realm实现仍然可以用于认证。

当标准领域通过检索存储的密码并将其与用户提供的值进行比较进行身份验证时,您可以通过在元素中放置元素来选择消化的密码 。支持SSHA,SHA或MD5算法之一的简单选择就是使用。必须将此元素配置为该类支持的摘要算法之一(SSHA,SHA或MD5)。选择此选项时,存储在密码中的密码内容必须是密码的明文版本,由指定的算法消化。 CredentialHandler<Realm>MessageDigestCredentialHandlerjava.security.MessageDigestRealm

authenticate()调用Realm 的方法时,用户指定的(明文)密码本身被相同的算法消化,并将结果与​​返回的值进行比较 Realm。相等匹配意味着原始密码的明文版本与用户提供的密码版本相同,因此应该授权该用户。

要计算明文密码的消化值,需要支持两种便捷技术:

  • 如果您正在编写需要动态计算消化密码的应用程序,请调用该类的静态Digest()方法 org.apache.catalina.realm.RealmBase,将明文密码,摘要算法名称和编码作为参数传递。此方法将返回已消化的密码。
  • 如果要执行命令行实用程序来计算消化密码,只需执行即可
    CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password}
    此明文密码的消化版本将返回标准输出。

如果使用具有DIGEST认证的消化密码,则用于生成摘要的明文不同,摘要必须使用MD5算法的一次迭代而不使用盐。在上面的例子中 {cleartext-password}必须替换为 {username}:{realm}:{cleartext-password}。例如,在开发环境中,这可能采用这种形式 testUser:Authentication required:testPassword。值 {realm}取自<realm-name> Web应用程序的元素<login-config>。如果未在web.xml中指定,Authentication required则使用默认值。

使用支持使用平台默认以外的编码的用户名和/或密码

CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} -e {encoding} {input}

但需要注意确保输入正确传递到消化器。蒸煮器返回{input}:{digest}。如果输入在返回中显示为已损坏,则摘要将无效。

摘要的输出格式是{salt}${iterations}${digest}。如果salt长度为零且迭代计数为1,则输出将简化为{digest}

完整的语法CATALINA_HOME/bin/digest.[bat|sh]是:

CATALINA_HOME/bin/digest.[bat|sh] [-a <algorithm>] [-e <encoding>]
        [-i <iterations>] [-s <salt-length>] [-k <key-length>]
        [-h <handler-class-name>] <credentials>
  • -a - 用于生成存储凭证的算法。如果未指定,将使用处理程序的默认值。如果既未指定处理程序也未指定算法,SHA-512则将使用默认值
  • -e - 用于字符转换的任何字节的编码,可能是必需的。如果未指定,将使用系统encoding(Charset#defaultCharset())。
  • -i - 生成存储凭据时要使用的迭代次数。如果未指定,将使用CredentialHandler的默认值。
  • -s - 作为凭证​​的一部分生成和存储的salt的长度(以字节为单位)。如果未指定,将使用CredentialHandler的默认值。
  • -k - 生成凭证时创建的密钥的长度(以位为单位)(如果有)。如果未指定,将使用CredentialHandler的默认值。
  • -h - 要使用的CredentialHandler的完全限定类名。如果未指定,将依次测试内置处理程序(MessageDigestCredentialHandler,然后是SecretKeyCredentialHandler),并将使用第一个接受指定算法的处理程序。

示例应用

Tomcat附带的示例应用程序包括受安全约束保护的区域,利用基于表单的登录。要访问它,请将浏览器指向 http:// localhost:8080 / examples / jsp / security / protected /, 然后使用为默认UserDatabaseRealm描述的用户名和密码之一登录 。

经理申请

如果您希望使用Manager应用 程序在正在运行的Tomcat安装中部署和取消部署应用程序,则必须将“manager-gui”角色添加到所选Realm实现中的至少一个用户名。这是因为管理器Web应用程序本身使用安全约束,该约束要求角色“manager-gui”访问该应用程序的HTML界面内的任何请求URI。

出于安全原因,默认Realm中没有用户名(即使用 conf/tomcat-users.xml被分配了“manager-gui”角色。因此,在Tomcat管理员专门为一个或多个用户分配此角色之前,没有人能够利用此应用程序的功能。

领域记录

由a记录的调试和异常消息将由Realm与域的容器相关联的日志记录配置记录:其周围的Context, Host或 Engine

标准领域实现

JDBCRealm

介绍

JDBCRealm是Tomcat Realm接口的实现, 它在通过JDBC驱动程序访问的关系数据库中查找用户。只要您的数据库结构符合以下要求,就可以使用大量的配置灵活性来适应现有的表名和列名:

  • 必须有一个表,在下面引用为users表,其中包含一个Realm 应该识别的每个有效用户的行。
  • 用户表必须包含至少两列(它可能包含更多的如果你的程序需要它):
    • 用户登录时由Tomcat识别的用户名。
    • 用户登录时由Tomcat识别的密码。此值可以明文或消化 - 有关详细信息,请参阅下文。
  • 必须有一个表,在下面引用为用户角色表,其中包含分配给特定用户的每个有效角色的一行。用户拥有零个,一个或多个有效角色是合法的。
  • 用户角色表格必须包括至少两列(它可能包含更多的如果你的程序需要它):
    • Tomcat要识别的用户名(与users表中指定的值相同)。
    • 与此用户关联的有效角色的角色名称。

 

领域配置

要设置Tomcat以使用JDBCRealm,您需要执行以下步骤:

  1. 如果尚未执行此操作,请在数据库中创建符合上述要求的表和列。
  2. 配置供Tomcat使用的数据库用户名和密码,该用户名和密码至少具有对上述表的只读权限。(Tomcat永远不会尝试写入这些表。)
  3. $CATALINA_HOME/lib目录中放置要使用的JDBC驱动程序的副本 。请注意,只能识别JAR文件!
  4. <Realm>$CATALINA_BASE/conf/server.xml文件中设置元素,如下所述 。
  5. 如果Tomcat已在运行,请重新启动它。

领域元素属性

要配置JDBCRealm,您将创建一个<Realm> 元素并将其嵌套在您的$CATALINA_BASE/conf/server.xml文件中,如上所述。JDBCRealm的属性在Realm配置文档中定义。

用于创建所需表的示例SQL脚本可能如下所示(根据特定数据库的需要调整语法):

create table users (
  user_name         varchar(15) not null primary key,
  user_pass         varchar(15) not null
);

create table user_roles (
  user_name         varchar(15) not null,
  role_name         varchar(15) not null,
  primary key (user_name, role_name)
);

示例Realm元素包含(注释掉)在默认$CATALINA_BASE/conf/server.xml文件中。下面是使用名为“authority”的MySQL数据库的示例,该数据库使用上述表配置,并使用用户名“dbuser”和密码“dbpass”进行访问:

<Realm className="org.apache.catalina.realm.JDBCRealm"
      driverName="org.gjt.mm.mysql.Driver"
   connectionURL="jdbc:mysql://localhost/authority?user=dbuser&amp;password=dbpass"
       userTable="users" userNameCol="user_name" userCredCol="user_pass"
   userRoleTable="user_roles" roleNameCol="role_name"/>

补充说明

JDBCRealm根据以下规则运行:

  • 当用户第一次尝试访问受保护资源时,Tomcat将调用此authenticate()方法 Realm。因此,您将立即反映您对数据库所做的任何更改(新用户,更改的密码或角色等)。
  • 一旦用户通过身份验证,用户(及其相关角色)将在用户登录期间缓存在Tomcat中。(对于基于FORM的身份验证,这意味着在会话超时或无效之前;对于BASIC身份验证,这意味着直到用户关闭其浏览器)。不会跨会话序列化保存和还原高速缓存的用户。对于一个已经验证的用户数据库信息的任何更改将被反映用户再次登录,直到下一次。
  • 管理用户用户角色 表中的信息是您自己的应用程序的责任。Tomcat不提供任何内置功能来维护用户和角色。

DataSourceRealm

介绍

DataSourceRealm是Tomcat Realm接口的一个实现, 它在通过名为JDBC DataSource的JNDI访问的关系数据库中查找用户。只要您的数据库结构符合以下要求,就可以使用大量的配置灵活性来适应现有的表名和列名:

  • 必须有一个表,在下面引用为users表,其中包含一个Realm 应该识别的每个有效用户的行。
  • 用户表必须包含至少两列(它可能包含更多的如果你的程序需要它):
    • 用户登录时由Tomcat识别的用户名。
    • 用户登录时由Tomcat识别的密码。此值可以明文或消化 - 有关详细信息,请参阅下文。
  • 必须有一个表,在下面引用为用户角色表,其中包含分配给特定用户的每个有效角色的一行。用户拥有零个,一个或多个有效角色是合法的。
  • 用户角色表格必须包括至少两列(它可能包含更多的如果你的程序需要它):
    • Tomcat要识别的用户名(与users表中指定的值相同)。
    • 与此用户关联的有效角色的角色名称。

快速开始

要设置Tomcat以使用DataSourceRealm,您需要执行以下步骤:

  1. 如果尚未执行此操作,请在数据库中创建符合上述要求的表和列。
  2. 配置供Tomcat使用的数据库用户名和密码,该用户名和密码至少具有对上述表的只读权限。(Tomcat永远不会尝试写入这些表。)
  3. 为数据库配置名为JDBC DataSource的JNDI。有关如何配置名为JDBC DataSource的JNDI的信息,请参阅 JNDI DataSource示例HOW-TO。一定要设置RealmlocalDataSource 适当属性,取决于JNDI的DataSource的定义在哪里。
  4. <Realm>$CATALINA_BASE/conf/server.xml文件中设置元素,如下所述 。
  5. 如果Tomcat已在运行,请重新启动它。

领域元素属性

要配置DataSourceRealm,您将创建一个<Realm> 元素并将其嵌套在您的$CATALINA_BASE/conf/server.xml文件中,如上所述。DataSourceRealm的属性在Realm 配置文档中定义。

用于创建所需表的示例SQL脚本可能如下所示(根据特定数据库的需要调整语法):

create table users (
  user_name         varchar(15) not null primary key,
  user_pass         varchar(15) not null
);

create table user_roles (
  user_name         varchar(15) not null,
  role_name         varchar(15) not null,
  primary key (user_name, role_name)
);

下面是使用名为“authority”的MySQL数据库的示例,该数据库使用上述表配置,并使用名为“java:/ comp / env / jdbc / authority”的JNDI JDBC DataSource进行访问。

<Realm className="org.apache.catalina.realm.DataSourceRealm"
   dataSourceName="jdbc/authority"
   userTable="users" userNameCol="user_name" userCredCol="user_pass"
   userRoleTable="user_roles" roleNameCol="role_name"/>

补充说明

DataSourceRealm根据以下规则运行:

  • 当用户第一次尝试访问受保护资源时,Tomcat将调用此authenticate()方法 Realm。因此,您将立即反映您对数据库所做的任何更改(新用户,更改的密码或角色等)。
  • 一旦用户通过身份验证,用户(及其相关角色)将在用户登录期间缓存在Tomcat中。(对于基于FORM的身份验证,这意味着在会话超时或无效之前;对于BASIC身份验证,这意味着直到用户关闭其浏览器)。不会跨会话序列化保存和还原高速缓存的用户。对于一个已经验证的用户数据库信息的任何更改将被反映用户再次登录,直到下一次。
  • 管理用户用户角色 表中的信息是您自己的应用程序的责任。Tomcat不提供任何内置功能来维护用户和角色。

JNDIRealm

介绍

JNDIRealm是Tomcat Realm接口的实现, 它在JNDI提供程序(通常是JNDI API类可用的标准LDAP提供程序)访问的LDAP目录服务器中查找用户。该领域支持使用目录进行身份验证的各种方法。

连接到目录

领域与目录的连接由connectionURL配置属性定义 。这是一个URL,其格式由JNDI提供程序定义。它通常是一个LDAP URL,它指定要连接的目录服务器的域名,以及可选的所需根命名上下文的端口号和可分辨名称(DN)。

如果您有多个提供程序,则可以配置 alternateURL。如果一个套接字连接不能对供应商在做的ConnectionURL的将尝试使用alternateURL

在进行连接以搜索目录并检索用户和角色信息时,域将使用connectionName和 connectionPassword属性指定的用户名和密码对目录进行身份验证 。如果未指定这些属性,则连接是匿名的。在许多情况下这已足够。

选择用户的目录条目

每个可以进行身份​​验证的用户必须DirContext通过与connectionURL属性定义 的初始元素对应的单个条目在目录中表示。此用户条目必须具有包含用于身份验证的用户名的属性。

通常,用户条目的可分辨名称包含用于身份验证的用户名,但对于所有用户而言都是相同的。在这种情况下,userPattern属性可用于指定DN,“{0}”标记用户名应替换的位置。

否则,领域必须搜索目录以查找包含用户名的唯一条目。以下属性配置此搜索:

  • userBase - 作为包含用户的子树的基础的条目。如果未指定,则搜索库是顶级上下文。
  • userSubtree - 搜索范围。设置为 true,如果你想搜索的根的整个子树的用户群条目。false请求单级搜索的默认值,仅包括顶级。
  • userSearch - 指定替换用户名后要使用的LDAP搜索过滤器的模式。

验证用户

  • 绑定模式

    默认情况下,域通过绑定到具有该用户的条目的DN和用户呈现的密码的目录来验证用户。如果此简单绑定成功,则认为用户已通过身份验证。

    出于安全原因,目录可以存储用户密码的摘要而不是明文版本(有关更多信息,请参阅 消化密码)。在这种情况下,作为简单绑定操作的一部分,目录自动计算用户提供的明文密码的正确摘要,然后再根据存储的值进行验证。因此,在绑定模式中,域不涉及摘要处理。未使用摘要属性,如果设置,将忽略该 属性。

  • 比较模式

    或者,领域可以从目录中检索存储的密码,并将其明确地与用户呈现的值进行比较。通过将userPassword属性设置为包含密码的用户条目中的目录属性的名称来配置此模式 。

    比较模式有一些缺点。首先, 必须配置connectionName和 connectionPassword属性以允许领域读取目录中的用户密码。出于安全原因,这通常是不可取的; 实际上,许多目录实现甚至不允许目录管理器读取这些密码。此外,领域必须自己处理密码摘要,包括所用算法的变化以及在目录中表示密码哈希的方式。但是,领域有时可能需要访问存储的密码,例如,以支持HTTP摘要访问身份验证(RFC 2069)。(注意,HTTP摘要认证与存储库中用于用户信息的密码摘要的存储不同,如上所述)。

为用户分配角色

目录领域支持两种在目录中表示角色的方法:

  • 角色作为显式目录条目

    角色可以由显式目录条目表示。角色条目通常是LDAP组条目,其中一个属性包含角色的名称,另一个属性的值是该角色中用户的可分辨名称或用户名。以下属性配置目录搜索以查找与经过身份验证的用户关联的角色的名称:

    • roleBase - 角色搜索的基本条目。如果未指定,则搜索库是顶级目录上下文。
    • roleSubtree - 搜索范围。设置为true,如果你想搜索的根的整个子树roleBase条目。false请求单级搜索的默认值,仅包括顶级。
    • roleSearch - 用于选择角色条目的LDAP搜索过滤器。它可选地包括用于可分辨名称的模式替换“{0}”和/或用于用户名的“{1}”和/或用于来自用户的目录条目的属性的“{2}”。使用userRoleAttribute指定提供“{2}”值的属性的名称。
    • roleName - 包含该角色名称的角色条目中的属性。
    • roleNested - 启用嵌套角色。true如果要在角色中嵌套角色,请设置为 。如果已配置,则将以递归方式尝试每个新找到的roleName和可分辨名称以进行新的角色搜索。默认值为false
  • 角色作为用户条目的属性

    角色名称也可以保存为用户目录条目中属性的值。使用userRoleName指定此属性的名称。

可以使用两种角色表示方法的组合。

快速开始

要设置Tomcat以使用JNDIRealm,您需要按照以下步骤操作:

  1. 确保您的目录服务器配置了符合上面列出的要求的架构。
  2. 如果需要,请配置供Tomcat使用的用户名和密码,该用户名和密码具有对上述信息的只读访问权限。(Tomcat永远不会尝试修改此信息。)
  3. <Realm>$CATALINA_BASE/conf/server.xml文件中设置元素,如下所述 。
  4. 如果Tomcat已在运行,请重新启动它。

领域元素属性

要配置JNDIRealm,您将创建一个<Realm> 元素并将其嵌套在您的$CATALINA_BASE/conf/server.xml文件中,如上所述。JNDIRealm的属性在Realm配置文档中定义。

在目录服务器中创建适当的模式超出了本文档的范围,因为它对每个目录服务器实现都是唯一的。在下面的示例中,我们假设您使用的是OpenLDAP目录服务器(版本2.0.11或更高版本)的分发版,可以从https://www.openldap.org下载 。假设您的slapd.conf文件包含以下设置(以及其他设置):

database ldbm
suffix dc="mycompany",dc="com"
rootdn "cn=Manager,dc=mycompany,dc=com"
rootpw secret

我们假设connectionURL目录服务器与Tomcat在同一台机器上运行。 有关配置和使用JNDI LDAP提供程序的详细信息,请参阅http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html

接下来,假设此目录服务器已填充了如下所示的元素(以LDIF格式):

# Define top-level entry
dn: dc=mycompany,dc=com
objectClass: dcObject
dc:mycompany

# Define an entry to contain people
# searches for users are based on this entry
dn: ou=people,dc=mycompany,dc=com
objectClass: organizationalUnit
ou: people

# Define a user entry for Janet Jones
dn: uid=jjones,ou=people,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: jjones
sn: jones
cn: janet jones
mail: j.jones@mycompany.com
userPassword: janet

# Define a user entry for Fred Bloggs
dn: uid=fbloggs,ou=people,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: fbloggs
sn: bloggs
cn: fred bloggs
mail: f.bloggs@mycompany.com
userPassword: fred

# Define an entry to contain LDAP groups
# searches for roles are based on this entry
dn: ou=groups,dc=mycompany,dc=com
objectClass: organizationalUnit
ou: groups

# Define an entry for the "tomcat" role
dn: cn=tomcat,ou=groups,dc=mycompany,dc=com
objectClass: groupOfUniqueNames
cn: tomcat
uniqueMember: uid=jjones,ou=people,dc=mycompany,dc=com
uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com

# Define an entry for the "role1" role
dn: cn=role1,ou=groups,dc=mycompany,dc=com
objectClass: groupOfUniqueNames
cn: role1
uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com

Realm如上所述配置的OpenLDAP目录服务器的示例元素可能如下所示,假设用户使用他们的uid(例如jjones)登录到应用程序,并且匿名连接足以搜索目录并检索角色信息:

<Realm   className="org.apache.catalina.realm.JNDIRealm"
     connectionURL="ldap://localhost:389"
       userPattern="uid={0},ou=people,dc=mycompany,dc=com"
          roleBase="ou=groups,dc=mycompany,dc=com"
          roleName="cn"
        roleSearch="(uniqueMember={0})"
/>

使用此配置,域将通过将用户名替换为用户名来确定用户的可分辨名称 userPattern,通过绑定到具有此DN的目录和从用户接收的密码进行身份验证,并搜索目录以查找用户的角色。

现在假设用户在登录时需要输入他们的电子邮件地址而不是用户ID。在这种情况下,领域必须在目录中搜索用户的条目。(当用户条目保存在可能与不同组织单位或公司位置相对应的多个子树中时,也需要进行搜索)。

此外,假设除了组条目之外,您还希望使用用户条目的属性来保存角色。现在Janet Jones的条目可能如下:

dn: uid=jjones,ou=people,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: jjones
sn: jones
cn: janet jones
mail: j.jones@mycompany.com
memberOf: role2
memberOf: role3
userPassword: janet

此领域配置将满足新要求:

<Realm   className="org.apache.catalina.realm.JNDIRealm"
     connectionURL="ldap://localhost:389"
          userBase="ou=people,dc=mycompany,dc=com"
        userSearch="(mail={0})"
      userRoleName="memberOf"
          roleBase="ou=groups,dc=mycompany,dc=com"
          roleName="cn"
        roleSearch="(uniqueMember={0})"
/>

现在,当Janet Jones以“j.jones@mycompany.com”身份登录时,领域会在目录中搜索具有该值作为其邮件属性的唯一条目,并尝试uid=jjones,ou=people,dc=mycompany,dc=com使用给定密码绑定到目录 。如果身份验证成功,则会为她分配三个角色:“role2”和“role3”,其目录条目中“memberOf”属性的值,以及“tomcat”,即唯一的组条目中“cn”属性的值她是会员。

最后,要通过从目录中检索密码并在领域中进行本地比较来验证用户,您可以使用如下的域配置:

<Realm   className="org.apache.catalina.realm.JNDIRealm"
    connectionName="cn=Manager,dc=mycompany,dc=com"
connectionPassword="secret"
     connectionURL="ldap://localhost:389"
      userPassword="userPassword"
       userPattern="uid={0},ou=people,dc=mycompany,dc=com"
          roleBase="ou=groups,dc=mycompany,dc=com"
          roleName="cn"
        roleSearch="(uniqueMember={0})"
/>

但是,如上所述,用于身份验证的默认绑定模式通常是首选。

补充说明

JNDIRealm按照以下规则运作:

  • 当用户第一次尝试访问受保护资源时,Tomcat将调用此authenticate()方法 Realm。因此,您将立即反映您对目录所做的任何更改(新用户,更改的密码或角色等)。
  • 一旦用户通过身份验证,用户(及其相关角色)将在用户登录期间缓存在Tomcat中。(对于基于FORM的身份验证,这意味着在会话超时或无效之前;对于BASIC身份验证,这意味着直到用户关闭其浏览器)。不会跨会话序列化保存和还原高速缓存的用户。对于一个已经验证的用户目录信息的任何更改将被反映用户再次登录,直到下一次。
  • 管理目录服务器中的信息是您自己的应用程序的责任。Tomcat不提供任何内置功能来维护用户和角色。

是UserDatabaseRealm

介绍

UserDatabaseRealm是Tomcat Realm接口的实现, 它使用JNDI资源来存储用户信息。默认情况下,JNDI资源由XML文件支持。它不是为大规模生产用途而设计的。在启动时,UserDatabaseRealm从XML文档加载有关所有用户及其相应角色的信息(默认情况下,从中加载此文档 $CATALINA_BASE/conf/tomcat-users.xml)。用户,他们的密码和他们的角色都可以动态编辑,通常是通过JMX。更改可能会保存并将反映在XML文件中。

领域元素属性

要配置UserDatabaseRealm,您将创建一个<Realm> 元素并将其嵌套在您的$CATALINA_BASE/conf/server.xml文件中,如上所述。UserDatabaseRealm的属性在Realm 配置文档中定义。

用户文件格式

users文件使用与MemoryRealm相同的格式 。

Tomcat的默认安装配置了嵌套在<Engine>元素内的UserDatabaseRealm ,因此它适用于所有虚拟主机和Web应用程序。该conf/tomcat-users.xml文件的默认内容 是:

<tomcat-users>
  <user username="tomcat" password="tomcat" roles="tomcat" />
  <user username="role1"  password="tomcat" roles="role1"  />
  <user username="both"   password="tomcat" roles="tomcat,role1" />
</tomcat-users>

补充说明

UserDatabaseRealm根据以下规则运行:

  • 当Tomcat首次启动时,它会从用户文件加载所有已定义的用户及其相关信息。在重新启动Tomcat之前,将无法识别对此文件中的数据所做的更改。可以通过UserDatabase资源进行更改。Tomcat提供了可以通过JMX访问的MBean。
  • 当用户第一次尝试访问受保护资源时,Tomcat将调用此authenticate()方法 Realm
  • 一旦用户通过身份验证,用户(及其相关角色)将在用户登录期间缓存在Tomcat中。(对于基于FORM的身份验证,这意味着在会话超时或无效之前;对于BASIC身份验证,这意味着直到用户关闭其浏览器)。不会跨会话序列化保存和还原高速缓存的用户。

MemoryRealm

介绍

MemoryRealm是Tomcat Realm接口的简单演示实现。它不是为生产用途而设计的。在启动时,MemoryRealm从XML文档加载有关所有用户及其相应角色的信息(默认情况下,加载此文档$CATALINA_BASE/conf/tomcat-users.xml)。在重新启动Tomcat之前,无法识别对此文件中数据的更改。

领域元素属性

要配置MemoryRealm,您将创建一个<Realm> 元素并将其嵌套在您的$CATALINA_BASE/conf/server.xml文件中,如上所述。MemoryRealm的属性在Realm配置文档中定义。

用户文件格式

users文件(默认情况下,conf/tomcat-users.xml必须是带有根元素的XML文档<tomcat-users>。嵌套在根元素内部将是<user>每个有效用户的元素,包含以下属性:

  • name - 此用户必须登录的用户
  • 密码 -密码该用户必须使用(明文如果登录digest属性未设置上 <Realm>所描述的元素,或适当地消化相反)。
  • roles - 以逗号分隔的与此用户关联的角色名称列表。

补充说明

MemoryRealm根据以下规则运行:

  • 当Tomcat首次启动时,它会从用户文件加载所有已定义的用户及其相关信息。在重新启动Tomcat之前,将无法识别对此文件中数据的更改。
  • 当用户第一次尝试访问受保护资源时,Tomcat将调用此authenticate()方法 Realm
  • 一旦用户通过身份验证,用户(及其相关角色)将在用户登录期间缓存在Tomcat中。(对于基于FORM的身份验证,这意味着在会话超时或无效之前;对于BASIC身份验证,这意味着直到用户关闭其浏览器)。不会跨会话序列化保存和还原高速缓存的用户。
  • 管理用户文件中的信息是您的应用程序的责任。Tomcat不提供任何内置功能来维护用户和角色。

JAASRealm

介绍

JAASRealm是Tomcat Realm接口的一个实现, 它通过Java身份验证和授权服务(JAAS)框架对用户进行身份验证,该框架现在作为标准Java SE API的一部分提供。

使用JAASRealm使开发人员能够将几乎任何可以想象的安全领域与Tomcat的CMA结合起来。

JAASRealm是基于JA 规范请求196的基于JAAS的J2EE v1.4 J2EE认证框架的Tomcat的原型,用于增强容器管理的安全性并促进其“可插入”认证机制,其实现与容器无关。

基于JAAS登录模块和主体(请参阅javax.security.auth.spi.LoginModule 和javax.security.Principal),您可以开发自己的安全机制或包装另一个第三方机制,以便与Tomcat实现的CMA集成。

快速开始

要设置Tomcat以将JAASRealm与您自己的JAAS登录模块一起使用,您需要执行以下步骤:

  1. 编写自己的基于JAAS的LoginModule,用户和角色类(请参阅 JAAS认证教程和 JAAS登录模块开发人员指南),由JAAS登录上下文管理(javax.security.auth.login.LoginContext)在开发LoginModule时,请注意JAASRealm的内置CallbackHandler 仅识别NameCallbackPasswordCallback目前。
  2. 虽然未在JAAS中指定,但您应创建单独的类来区分用户和角色,进行扩展javax.security.Principal,以便Tomcat可以告诉您从登录模块返回的哪些Principal是用户以及哪些是角色(请参阅参考资料org.apache.catalina.realm.JAASRealm)。无论如何,返回的第一个Principal 始终被视为用户Principal。
  3. 将已编译的类放在Tomcat的类路径上
  4. 设置Java的login.config文件(请参阅 JAAS LoginConfig文件)并通过指定其位置到JVM来告诉Tomcat在哪里找到它,例如通过设置环境变量:JAVA_OPTS=$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_BASE/conf/jaas.config
  5. 在web.xml中配置您要保护的资源的安全性约束
  6. 在server.xml中配置JAASRealm模块
  7. 如果Tomcat已在运行,请重新启动它。

领域元素属性

要按照上面的步骤6配置JAASRealm,您需要创建一个<Realm>元素并将其嵌套在节点中的 $CATALINA_BASE/conf/server.xml 文件中<Engine>。JAASRealm的属性在Realm 配置文档中定义。

以下是server.xml代码段的外观示例。

<Realm className="org.apache.catalina.realm.JAASRealm"
                appName="MyFooRealm"
    userClassNames="org.foobar.realm.FooUser"
     roleClassNames="org.foobar.realm.FooRole"/>

您的登录模块负责为user(javax.security.auth.Subject)创建和保存表示Principal的User和Role对象。如果您的登录模块没有创建用户对象但也没有抛出登录异常,那么Tomcat CMA将会中断,您将被留在http:// localhost:8080 / myapp / j_security_check URI或其他位置未指定的位置。

JAAS方法的灵活性有两方面:

  • 您可以在自己的登录模块中执行幕后需要的任何处理。
  • 您可以通过更改配置并重新启动服务器来插入完全不同的LoginModule,而无需对应用程序进行任何代码更改。

补充说明

  • 当用户第一次尝试访问受保护资源时,Tomcat将调用此authenticate() 方法Realm。因此,您将立即反映您在安全机制中所做的任何更改(新用户,更改的密码或角色等)。
  • 一旦用户通过身份验证,用户(及其相关角色)将在用户登录期间缓存在Tomcat中。对于基于FORM的身份验证,这意味着直到会话超时或无效; 对于BASIC身份验证,这意味着在用户关闭浏览器之前。对于一个已经验证的用户的安全信息的任何更改将 被反映用户再次登录,直到下一次。
  • 与其他Realm实现一样,如果<Realm>元素server.xml 包含digest属性,则支持消化密码; JAASRealm CallbackHandler 将在将密码传回给密码之前将其消化LoginModule

CombinedRealm

介绍

CombinedRealm是Tomcat Realm接口的一种实现, 它通过一个或多个子域对用户进行身份验证。

使用CombinedRealm使开发人员能够组合相同或不同类型的多个领域。这可以用于针对不同的源进行身份验证,在一个Realm失败的情况下提供回退,或者用于需要多个域的任何其他目的。

子领域由定义CombinedRealm的Realm元素内的嵌套元素 Realm定义。将按照Realm列出的顺序对每个进行身份验证。针对任何Realm的身份验证将足以验证用户身份。

领域元素属性

要配置CombinedRealm,创建一个<Realm> 在你的元素,其嵌套$CATALINA_BASE/conf/server.xml 在您的文件<Engine><Host>。您还可以嵌套在文件中的<Context>节点 内context.xml

下面是一个示例,说明您的server.xml代码段应该如何使用UserDatabase Realm和DataSource Realm。

<Realm className="org.apache.catalina.realm.CombinedRealm" >
   <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
   <Realm className="org.apache.catalina.realm.DataSourceRealm"
             dataSourceName="jdbc/authority"
             userTable="users" userNameCol="user_name" userCredCol="user_pass"
             userRoleTable="user_roles" roleNameCol="role_name"/>
</Realm>

LockOutRealm

介绍

LockOutRealm是Tomcat Realm接口的一个实现, 它扩展CombinedRealm以提供锁定功能,以便在给定时间段内有太多失败的身份验证尝试时提供用户锁定机制。

为确保正确操作,此领域中存在合理的同步程度。

此Realm不需要修改底层Realms或相关的用户存储机制。它通过记录所有失败的登录来实现这一点,包括那些不存在的用户。为了通过考虑向无效用户发出请求来防止DOS(从而导致此缓存增长),身份验证失败的用户列表的大小是有限的。

子领域由定义LockOutRealm的Realm元素内的嵌套元素 Realm定义。将按照Realm列出的顺序对每个进行身份验证。针对任何Realm的身份验证将足以验证用户身份。

领域元素属性

要配置LockOutRealm,创建一个<Realm> 在你的元素,其嵌套$CATALINA_BASE/conf/server.xml 在您的文件<Engine><Host>。您还可以嵌套在文件中的<Context>节点 内context.xml。LockOutRealm的属性在Realm 配置文档中定义。

下面是一个示例,说明您的server.xml代码段应该如何向用户数据库领域添加锁定功能。

<Realm className="org.apache.catalina.realm.LockOutRealm" >
   <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
</Realm>

 

 

 

SecurityManager

背景

Java SecurityManager允许Web浏览器在其自己的沙箱中运行applet,以防止不受信任的代码访问本地文件系统上的文件,连接到加载applet的主机以外的主机,等等。以同样的方式,SecurityManager保护您免受浏览器中运行的不受信任的applet的影响,在运行Tomcat时使用SecurityManager可以保护您的服务器免受木马servlet,JSP,JSP bean和标记库的影响。甚至是无意中的错误。

想象一下,如果有权在您的站点上发布JSP的人无意中在JSP中包含以下内容:

<% System.exit(1); %>

每次这个JSP由Tomcat执行时,Tomcat都会退出。使用Java SecurityManager只是系统管理员可以用来保护服务器安全可靠的另一道防线。

警告 - 已使用Tomcat代码库进行安全审核。大多数关键包都受到保护,并且已经实施了新的安全包保护机制。尽管如此,在允许不受信任的用户发布Web应用程序,JSP,servlet,bean或标记库之前,请确保您对SecurityManager配置感到满意。 但是,使用SecurityManager运行肯定比没有安全管理器运行更好。

权限

权限类用于定义Tomcat加载的类的权限。有许多Permission类是JDK的标准部分,您可以创建自己的Permission类,以便在您自己的Web应用程序中使用。这两种技术都在Tomcat中使用。

标准权限

这只是适用于Tomcat的标准系统SecurityManager权限类的简短摘要。有关 更多信息,请参见http://docs.oracle.com/javase/7/docs/technotes/guides/security/

  • java.util.PropertyPermission - 控制对JVM属性的读/写访问,例如java.home
  • java.lang.RuntimePermission -控制使用一些系统/运行时功能,如exit()和 exec()。还控制包访问/定义。
  • java.io.FilePermission - 控制对文件和目录的读/写/执行访问。
  • java.net.SocketPermission - 控制网络套接字的使用。
  • java.net.NetPermission - 控制多播网络连接的使用。
  • java.lang.reflect.ReflectPermission - 控制使用反射来进行类内省。
  • java.security.SecurityPermission - 控制对安全方法的访问。
  • java.security.AllPermission - 允许访问所有权限,就像在没有SecurityManager的情况下运行Tomcat一样。

使用SecurityManager配置Tomcat

策略文件格式

Java SecurityManager实现的安全策略在$CATALINA_BASE/conf/catalina.policy文件中配置。此文件完全替换java.policyJDK系统目录中存在的文件。catalina.policy可以手动编辑该文件,也可以使用 Java 1.2或更高版本附带的 policytool应用程序。

catalina.policy文件中的条目使用标准 java.policy文件格式,如下所示:

// Example policy file entry

grant [signedBy <signer>,] [codeBase <code source>] {
  permission  <class>  [<name> [, <action list>]];
};

授予权限时,signedBycodeBase条目是可选的。注释行以“//”开头,并以当前行的结尾结束。的codeBase是在URL的形式,和用于文件的URL可以使用${java.home} 和${catalina.home}属性(其扩展了由为它们定义的目录路径JAVA_HOME, CATALINA_HOMECATALINA_BASE环境变量)。

默认策略文件

默认$CATALINA_BASE/conf/catalina.policy文件如下所示:

// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ============================================================================
// catalina.policy - Security Policy Permissions for Tomcat
//
// This file contains a default set of security policies to be enforced (by the
// JVM) when Catalina is executed with the "-security" option.  In addition
// to the permissions granted here, the following additional permissions are
// granted to each web application:
//
// * Read access to the web application's document root directory
// * Read, write and delete access to the web application's working directory
// ============================================================================


// ========== SYSTEM CODE PERMISSIONS =========================================


// These permissions apply to javac
grant codeBase "file:${java.home}/lib/-" {
        permission java.security.AllPermission;
};

// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
        permission java.security.AllPermission;
};

// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/../lib/-" {
        permission java.security.AllPermission;
};

// These permissions apply to all shared system extensions when
// ${java.home} points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/lib/ext/-" {
        permission java.security.AllPermission;
};


// ========== CATALINA CODE PERMISSIONS =======================================


// These permissions apply to the daemon code
grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
        permission java.security.AllPermission;
};

// These permissions apply to the logging API
// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home},
// update this section accordingly.
//  grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..}
grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
        permission java.io.FilePermission
         "${java.home}${file.separator}lib${file.separator}logging.properties", "read";

        permission java.io.FilePermission
         "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
        permission java.io.FilePermission
         "${catalina.base}${file.separator}logs", "read, write";
        permission java.io.FilePermission
         "${catalina.base}${file.separator}logs${file.separator}*", "read, write, delete";

        permission java.lang.RuntimePermission "shutdownHooks";
        permission java.lang.RuntimePermission "getClassLoader";
        permission java.lang.RuntimePermission "setContextClassLoader";

        permission java.lang.management.ManagementPermission "monitor";

        permission java.util.logging.LoggingPermission "control";

        permission java.util.PropertyPermission "java.util.logging.config.class", "read";
        permission java.util.PropertyPermission "java.util.logging.config.file", "read";
        permission java.util.PropertyPermission "org.apache.juli.AsyncLoggerPollInterval", "read";
        permission java.util.PropertyPermission "org.apache.juli.AsyncMaxRecordCount", "read";
        permission java.util.PropertyPermission "org.apache.juli.AsyncOverflowDropType", "read";
        permission java.util.PropertyPermission "org.apache.juli.ClassLoaderLogManager.debug", "read";
        permission java.util.PropertyPermission "catalina.base", "read";

        // Note: To enable per context logging configuration, permit read access to
        // the appropriate file. Be sure that the logging configuration is
        // secure before enabling such access.
        // E.g. for the examples web application (uncomment and unwrap
        // the following to be on a single line):
        // permission java.io.FilePermission "${catalina.base}${file.separator}
        //  webapps${file.separator}examples${file.separator}WEB-INF
        //  ${file.separator}classes${file.separator}logging.properties", "read";
};

// These permissions apply to the server startup code
grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
        permission java.security.AllPermission;
};

// These permissions apply to the servlet API classes
// and those that are shared across all class loaders
// located in the "lib" directory
grant codeBase "file:${catalina.home}/lib/-" {
        permission java.security.AllPermission;
};


// If using a per instance lib directory, i.e. ${catalina.base}/lib,
// then the following permission will need to be uncommented
// grant codeBase "file:${catalina.base}/lib/-" {
//         permission java.security.AllPermission;
// };


// ========== WEB APPLICATION PERMISSIONS =====================================


// These permissions are granted by default to all web applications
// In addition, a web application will be given a read FilePermission
// for all files and directories in its document root.
grant {
    // Required for JNDI lookup of named JDBC DataSource's and
    // javamail named MimePart DataSource used to send mail
    permission java.util.PropertyPermission "java.home", "read";
    permission java.util.PropertyPermission "java.naming.*", "read";
    permission java.util.PropertyPermission "javax.sql.*", "read";

    // OS Specific properties to allow read access
    permission java.util.PropertyPermission "os.name", "read";
    permission java.util.PropertyPermission "os.version", "read";
    permission java.util.PropertyPermission "os.arch", "read";
    permission java.util.PropertyPermission "file.separator", "read";
    permission java.util.PropertyPermission "path.separator", "read";
    permission java.util.PropertyPermission "line.separator", "read";

    // JVM properties to allow read access
    permission java.util.PropertyPermission "java.version", "read";
    permission java.util.PropertyPermission "java.vendor", "read";
    permission java.util.PropertyPermission "java.vendor.url", "read";
    permission java.util.PropertyPermission "java.class.version", "read";
    permission java.util.PropertyPermission "java.specification.version", "read";
    permission java.util.PropertyPermission "java.specification.vendor", "read";
    permission java.util.PropertyPermission "java.specification.name", "read";

    permission java.util.PropertyPermission "java.vm.specification.version", "read";
    permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
    permission java.util.PropertyPermission "java.vm.specification.name", "read";
    permission java.util.PropertyPermission "java.vm.version", "read";
    permission java.util.PropertyPermission "java.vm.vendor", "read";
    permission java.util.PropertyPermission "java.vm.name", "read";

    // Required for OpenJMX
    permission java.lang.RuntimePermission "getAttribute";

    // Allow read of JAXP compliant XML parser debug
    permission java.util.PropertyPermission "jaxp.debug", "read";

    // All JSPs need to be able to read this package
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat";

    // Precompiled JSPs need access to these packages.
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
    permission java.lang.RuntimePermission
     "accessClassInPackage.org.apache.jasper.runtime.*";

    // Applications using WebSocket need to be able to access these packages
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket.server";
};


// The Manager application needs access to the following packages to support the
// session display functionality. It also requires the custom Tomcat
// DeployXmlPermission to enable the use of META-INF/context.xml
// These settings support the following configurations:
// - default CATALINA_HOME == CATALINA_BASE
// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE
// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME
grant codeBase "file:${catalina.base}/webapps/manager/-" {
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util";
    permission org.apache.catalina.security.DeployXmlPermission "manager";
};
grant codeBase "file:${catalina.home}/webapps/manager/-" {
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util";
    permission org.apache.catalina.security.DeployXmlPermission "manager";
};

// The Host Manager application needs the custom Tomcat DeployXmlPermission to
// enable the use of META-INF/context.xml
// These settings support the following configurations:
// - default CATALINA_HOME == CATALINA_BASE
// - CATALINA_HOME != CATALINA_BASE, per instance Host Manager in CATALINA_BASE
// - CATALINA_HOME != CATALINA_BASE, shared Host Manager in CATALINA_HOME
grant codeBase "file:${catalina.base}/webapps/host-manager/-" {
    permission org.apache.catalina.security.DeployXmlPermission "host-manager";
};
grant codeBase "file:${catalina.home}/webapps/host-manager/-" {
    permission org.apache.catalina.security.DeployXmlPermission "host-manager";
};


// You can assign additional permissions to particular web applications by
// adding additional "grant" entries here, based on the code base for that
// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
//
// Different permissions can be granted to JSP pages, classes loaded from
// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
//
// For instance, assume that the standard "examples" application
// included a JDBC driver that needed to establish a network connection to the
// corresponding database and used the scrape taglib to get the weather from
// the NOAA web server.  You might create a "grant" entries like this:
//
// The permissions granted to the context root directory apply to JSP pages.
// grant codeBase "file:${catalina.base}/webapps/examples/-" {
//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };
//
// The permissions granted to the context WEB-INF/classes directory
// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" {
// };
//
// The permission granted to your JDBC driver
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
// };
// The permission granted to the scrape taglib
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };

// To grant permissions for web applications using packed WAR files, use the
// Tomcat specific WAR url scheme.
//
// The permissions granted to the entire web application
// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/-" {
// };
//
// The permissions granted to a specific JAR
// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/WEB-INF/lib/foo.jar" {
// };

使用SecurityManager启动Tomcat

配置catalina.policy文件以用于SecurityManager后,可以使用“-security”选项使用SecurityManager启动Tomcat:

$CATALINA_HOME/bin/catalina.sh start -security    (Unix)
%CATALINA_HOME%\bin\catalina start -security      (Windows)

打包WAR文件的权限

使用打包的WAR文件时,必须使用Tomcat的自定义war URL协议为Web应用程序代码分配权限。

要为整个Web应用程序分配权限,策略文件中的条目将如下所示:

// Example policy file entry
grant codeBase "war:file:${catalina.base}/webapps/examples.war*/-" {
    ...
};

要为Web应用程序中的单个JAR分配权限,策略文件中的条目将如下所示:

// Example policy file entry
grant codeBase "war:file:${catalina.base}/webapps/examples.war*/WEB-INF/lib/foo.jar" {
    ...
};

在Tomcat中配置程序包保护

从Tomcat 5开始,现在可以配置哪个Tomcat内部包受到保护以防止包定义和访问。有关 更多信息,请参阅http://www.oracle.com/technetwork/java/seccodeguide-139067.html

警告:请注意,删除默认程序包保护可能会打开安全漏洞

默认属性文件

默认$CATALINA_BASE/conf/catalina.properties文件如下所示:

#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,
org.apache.jasper.
#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageDefinition unless the
# corresponding RuntimePermission ("defineClassInPackage."+package) has
# been granted.
#
# by default, no packages are restricted for definition, and none of
# the class loaders supplied with the JDK call checkPackageDefinition.
#
package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,
org.apache.tomcat.,org.apache.jasper.

配置catalina.properties文件以与SecurityManager一起使用后,请记住重新启动Tomcat。

故障排除

如果您的Web应用程序尝试执行缺少必需权限而禁止的操作,则会 在SecurityManager检测到违规时抛出一个 AccessControLException或一个SecurityException。调试缺少的权限可能具有挑战性,一个选项是打开执行期间所做的所有安全决策的调试输出。这是通过在启动Tomcat之前设置系统属性来完成的。最简单的方法是通过CATALINA_OPTS环境变量。执行以下命令:

export CATALINA_OPTS=-Djava.security.debug=all    (Unix)
set CATALINA_OPTS=-Djava.security.debug=all       (Windows)

在启动Tomcat之前。

警告 - 这将产生许多兆字节 的输出!但是,它可以帮助您通过搜索单词“FAILED”并确定正在检查哪个权限来追踪问题。有关您可以在此处指定的更多选项,请参阅Java安全性文档。

 

JNDI资源如何

介绍

Tomcat 以与 Java Enterprise Edition应用程序服务器提供的方式兼容的方式为在其下运行的每个Web应用程序提供JNDI InitialContext实现实例 。Java EE标准在文件中提供了一组标准元素来引用/定义资源。/WEB-INF/web.xml

有关为JNDI编程API以及Java Enterprise Edition(Java EE)服务器支持的功能的更多信息,请参阅以下规范,Tomcat为其提供的服务模拟这些功能:

web.xml配置

可以在Web应用程序的Web应用程序部署描述符(/WEB-INF/web.xml)中使用以下元素来定义资源:

  • <env-entry> - 环境条目,单值参数,可用于配置应用程序的运行方式。
  • <resource-ref>- 资源引用,通常是对象工厂的资源,例如JDBC DataSource,JavaMail Session或配置到Tomcat中的自定义对象工厂。
  • <resource-env-ref>- 资源环境引用,resource-ref Servlet 2.4 中添加的新变体,可以更轻松地为不需要身份验证信息的资源进行配置。

如果Tomcat能够识别用于创建资源的适当资源工厂,并且不需要进一步的配置信息,则Tomcat将使用该信息/WEB-INF/web.xml来创建资源。

Tomcat为JNDI资源提供了许多无法在web.xml中指定的特定于Tomcat的选项。这些包括closeMethod在Web应用程序停止时更快地清理JNDI资源,并 singleton控制是否为每个JNDI查找创建新资源实例。要使用这些配置选项,必须在Web应用程序的<Context>元素或 元素中 指定资源 。<GlobalNamingResources>$CATALINA_BASE/conf/server.xml

context.xml配置

如果Tomcat无法识别相应的资源工厂和/或需要其他配置信息,则必须在Tomcat创建资源之前指定其他特定于Tomcat的配置。Tomcat特定资源配置输入<Context>到可以$CATALINA_BASE/conf/server.xml在每个Web应用程序上下文XML文件(META-INF/context.xml)中指定的元素中,或者最好在每个Web应用程序上下文XML文件()中指定。

使用元素中的以下元素执行Tomcat特定资源配置<Context> :

  • <Environment> - 为将通过JNDI向Web应用程序公开的标量环境条目配置名称和值 InitialContext(相当于<env-entry>在Web应用程序部署描述符中包含元素)。
  • <Resource> - 配置应用程序可用资源的名称和数据类型(相当于<resource-ref>在Web应用程序部署描述符中包含 元素)。
  • <ResourceLink> - 添加指向全局JNDI上下文中定义的资源的链接。使用资源链接为Web应用程序提供对<Server> 元素的<GlobalNamingResources> 子元素中定义的资源的访问权限。
  • <Transaction> - 添加资源工厂,用于实例化可用的UserTransaction对象实例java:comp/UserTransaction

任何数量的这些元素都可以嵌套在 <Context>元素中,并且只与该特定的Web应用程序相关联。

如果在<Context>元素中定义了资源 ,则不必定义该资源/WEB-INF/web.xml。但是,建议保留该条目/WEB-INF/web.xml 以记录Web应用程序的资源要求。

如果为<env-entry>Web应用程序部署描述符(/WEB-INF/web.xml)中 包含的元素定义了相同的资源名称,并且在作为Web应用程序<Environment>元素的一部分的 <Context>元素中定义了相同的资源名称 ,则只有相应<Environment>元素允许时, 部署描述符中的值才会优先。 (通过将override 属性设置为“true”)。

全局配置

Tomcat为整个服务器维护一个单独的全局资源命名空间。这些是在元素中配置 的 。您可以使用<ResourceLink>将这些资源公开给Web应用程序, 以将其包含在每个Web应用程序上下文中。 <GlobalNamingResources>$CATALINA_BASE/conf/server.xml

如果使用<ResourceLink>定义了 资源,则不必定义该资源/WEB-INF/web.xml。但是,建议保留该条目/WEB-INF/web.xml 以记录Web应用程序的资源要求。

使用资源

InitialContext被配置作为网络应用程序最初部署,并且提供给Web应用程序组件(用于只读访问)。所有配置的条目和资源都放在java:comp/envJNDI命名空间的部分中,因此对资源的典型访问 - 在本例中为JDBC DataSource- 看起来像这样:

// Obtain our environment naming context
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");

// Look up our data source
DataSource ds = (DataSource)
  envCtx.lookup("jdbc/EmployeeDB");

// Allocate and use a connection from the pool
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();

Tomcat标准资源工厂

Tomcat包含一系列标准资源工厂,可以为您的Web应用程序提供服务,但为您提供配置灵活性(通过 <Context>元素),而无需修改Web应用程序或部署描述符。下面的每个小节详细说明了标准资源工厂的配置和使用。

有关如何使用Tomcat创建,安装,配置和使用自己的自定义资源工厂类的信息,请参阅添加自定义资源工厂

 - 在标准资源工厂中,只有“JDBC数据源”和“用户事务”工厂被强制在其他平台上可用,然后只有在平台实现Java Enterprise Edition(Java EE)规范时才需要它们。所有其他标准资源工厂以及您自己编写的自定义资源工厂都特定于Tomcat,并且不能假定在其他容器上可用。

通用JavaBean资源

0.简介

此资源工厂可用于创建 符合标准JavaBeans命名约定的任何 Java类的对象(即,它具有零参数构造函数,并且具有符合setFoo()命名模式的属性设置器。资源工厂将仅创建lookup()如果singleton 工厂的属性设置为,则每次为此条目创建适当的bean类的新实例 false

使用该设施所需的步骤如下所述。

1.创建JavaBean类

创建JavaBean类,每次查找资源工厂时都会实例化它。对于此示例,假设您创建了一个类com.mycompany.MyBean,如下所示:

package com.mycompany;

public class MyBean {

  private String foo = "Default Foo";

  public String getFoo() {
    return (this.foo);
  }

  public void setFoo(String foo) {
    this.foo = foo;
  }

  private int bar = 0;

  public int getBar() {
    return (this.bar);
  }

  public void setBar(int bar) {
    this.bar = bar;
  }


}

2.声明您的资源要求

接下来,修改Web应用程序部署描述符(/WEB-INF/web.xml)以声明JNDI名称,在该名称下将请求此Bean的新实例。最简单的方法是使用一个<resource-env-ref>元素,如下所示:

<resource-env-ref>
  <description>
    Object factory for MyBean instances.
  </description>
  <resource-env-ref-name>
    bean/MyBeanFactory
  </resource-env-ref-name>
  <resource-env-ref-type>
    com.mycompany.MyBean
  </resource-env-ref-type>
</resource-env-ref>

警告 - 请确保遵守DTD对Web应用程序部署描述符所要求的元素排序!有关详细信息,请参阅 Servlet规范

3.编写应用程序对此资源的使用

此资源环境引用的典型用法可能如下所示:

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");

writer.println("foo = " + bean.getFoo() + ", bar = " +
               bean.getBar());

4.配置Tomcat的资源工厂

要配置Tomcat的资源工厂,请将此类元素添加<Context>到此Web应用程序的 元素中。

<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean"
            factory="org.apache.naming.factory.BeanFactory"
            bar="23"/>
  ...
</Context>

请注意,资源名称(此处bean/MyBeanFactory 必须与Web应用程序部署描述符中指定的值匹配。我们还初始化bar 属性的值,这将导致setBar(23)在返回新bean之前调用。因为我们没有初始化 foo属性(虽然我们可以),bean将包含其构造函数设置的任何默认值。

某些bean具有不能从字符串值自动转换的类型的属性。使用Tomcat BeanFactory设置此类属性将失败并出现NamingException。如果这些bean提供了从字符串值设置属性的方法,则可以将Tomcat BeanFactory配置为使用这些方法。配置使用forceString属性完成。

假设我们的bean看起来像这样:

package com.mycompany;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class MyBean2 {

  private InetAddress local = null;

  public InetAddress getLocal() {
    return local;
  }

  public void setLocal(InetAddress ip) {
    local = ip;
  }

  public void setLocal(String localHost) {
    try {
      local = InetAddress.getByName(localHost);
    } catch (UnknownHostException ex) {
    }
  }

  private InetAddress remote = null;

  public InetAddress getRemote() {
    return remote;
  }

  public void setRemote(InetAddress ip) {
    remote = ip;
  }

  public void host(String remoteHost) {
    try {
      remote = InetAddress.getByName(remoteHost);
    } catch (UnknownHostException ex) {
    }
  }

}

bean有两个属性,都属于类型InetAddress。第一个属性local有一个附加的setter,它接受一个字符串参数。默认情况下,Tomcat BeanFactory会尝试使用与属性类型具有相同参数类型的自动检测到的setter,然后抛出NamingException,因为它不准备将给定的字符串属性值转换为InetAddress。我们可以告诉Tomcat BeanFactory使用其他类似的setter:

<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean2"
            factory="org.apache.naming.factory.BeanFactory"
            forceString="local"
            local="localhost"/>
  ...
</Context>

bean属性remote也可以从字符串设置,但必须使用非标准方法名称host。要设置localremote使用以下配置:

<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean2"
            factory="org.apache.naming.factory.BeanFactory"
            forceString="local,remote=host"
            local="localhost"
            remote="tomcat.apache.org"/>
  ...
</Context>

可以forceString通过串联逗号作为分隔符来组合多个属性描述 。每个属性描述都只包含属性名称,在这种情况下BeanFactory调用setter方法。或者它包括name=method在哪种情况下,name通过调用方法设置名为property的属性 method。对于类型String或原始类型的属性或其相关的原始包装类, forceString不需要使用。将自动检测正确的setter并应用参数转换。

用户数据库资源

0.简介

UserDatabase资源通常配置为UserDatabase领域使用的全局资源。Tomcat包含一个UserDatabaseFactory,用于创建由XML文件支持的UserDatabase资源 - 通常tomcat-users.xml

设置全局UserDatabase资源所需的步骤如下所述。

1.创建/编辑XML文件

$CATALINA_BASE/conf/tomcat-users.xml但是,XML文件通常位于 文件系统的任何位置,您可以自由地找到该文件。建议放置XML文件$CATALINA_BASE/conf。典型的XML看起来像:

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>

2.声明你的资源

接下来,修改$CATALINA_BASE/conf/server.xml以基于XML文件创建UserDatabase资源。它应该看起来像这样:

<Resource name="UserDatabase"
          auth="Container"
          type="org.apache.catalina.UserDatabase"
          description="User database that can be updated and saved"
          factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
          pathname="conf/tomcat-users.xml"
          readonly="false" />

pathname属性可以是URL,绝对路径或相对路径。如果相对,则相对于$CATALINA_BASE

readonly属性是可选的,true如果未提供,则默认为 。如果XML是可写的,那么它将在Tomcat启动时写入。警告:写入文件时,它将继承Tomcat运行的用户的默认文件权限。确保这些适合维护安装的安全性。

如果在Realm中引用,则默认情况下,UserDatabse将监视 pathname更改并在观察到上次修改时间的更改时重新加载文件。可以通过将watchSource属性设置为禁用此功能 false

3.配置领域

配置UserDatabase域以使用Realm配置文档中所述的此资源 。

JavaMail会话

0.简介

在许多Web应用程序中,发送电子邮件消息是系统功能的必要部分。在 Java邮件 API使这个过程相对简单,但需要很多配置细节,客户端应用程序必须知道的(包括SMTP主机被用于报文发送的名称)。

Tomcat包含一个标准资源工厂,它将javax.mail.Session为您创建 会话实例,已配置为连接到SMTP服务器。通过这种方式,应用程序完全不受电子邮件服务器配置环境中的更改的影响 - 它只需要在需要时请求并接收预配置的会话。

下面概述了所需的步骤。

1.声明您的资源要求

您应该做的第一件事是修改Web应用程序部署描述符(/WEB-INF/web.xml)以声明JNDI名称,您将在该名称下查找预配置的会话。按照惯例,所有这些名称都应该解析为mail子上下文(相对于作为java:comp/env所有提供的资源工厂的根的标准命名上下文。典型的web.xml条目可能如下所示:

<resource-ref>
  <description>
    Resource reference to a factory for javax.mail.Session
    instances that may be used for sending electronic mail
    messages, preconfigured to connect to the appropriate
    SMTP server.
  </description>
  <res-ref-name>
    mail/Session
  </res-ref-name>
  <res-type>
    javax.mail.Session
  </res-type>
  <res-auth>
    Container
  </res-auth>
</resource-ref>

警告 - 请确保遵守DTD对Web应用程序部署描述符所要求的元素排序!有关详细信息,请参阅 Servlet规范

2.编写应用程序对此资源的使用

此资源引用的典型用法可能如下所示:

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
Session session = (Session) envCtx.lookup("mail/Session");

Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(request.getParameter("from")));
InternetAddress to[] = new InternetAddress[1];
to[0] = new InternetAddress(request.getParameter("to"));
message.setRecipients(Message.RecipientType.TO, to);
message.setSubject(request.getParameter("subject"));
message.setContent(request.getParameter("content"), "text/plain");
Transport.send(message);

请注意,应用程序使用在Web应用程序部署描述符中声明的相同资源引用名称。这与<Context>在Web应用程序的元素中配置的资源工厂相匹配, 如下所述。

3.配置Tomcat的资源工厂

要配置Tomcat的资源工厂,请将此类元素添加<Context>到此Web应用程序的 元素中。

<Context ...>
  ...
  <Resource name="mail/Session" auth="Container"
            type="javax.mail.Session"
            mail.smtp.host="localhost"/>
  ...
</Context>

请注意,资源名称(此处mail/Session)必须与Web应用程序部署描述符中指定的值匹配。自定义mail.smtp.host参数的值以指向为网络提供SMTP服务的服务器。

其他资源属性和值将转换为属性和值,并javax.mail.Session.getInstance(java.util.Properties)作为java.util.Properties集合的一部分传递给它们。除了JavaMail规范的附录A中定义的属性之外,各个提供程序还可以支持其他属性。

如果资源配置与password属性以及一个mail.smtp.usermail.user属性,那么Tomcat的资源工厂将配置并添加 javax.mail.Authenticator到邮件会话。

4.安装JavaMail库

下载JavaMail API

解压缩发行版并将mail.jar放入$ CATALINA_HOME / lib中,以便在初始化邮件会话资源期间Tomcat可以使用它。注意:将此jar放在$ CATALINA_HOME / lib和Web应用程序的lib文件夹中都会导致错误,因此请确保仅将其放在$ CATALINA_HOME / lib位置。

5.重启Tomcat

为了使Tomcat可以看到其他JAR,必须重新启动Tomcat实例。

示例应用

/examplesTomcat附带的应用程序包含使用此资源工厂的示例。可以通过“JSP Examples”链接访问它。实际发送邮件消息的servlet的源代码是 /WEB-INF/classes/SendMailServlet.java

警告 - 默认配置假定端口25上有SMTP服务器列表localhost。如果不是这种情况,请编辑<Context>此Web应用程序的 元素,并将参数的参数值修改为mail.smtp.host网络上SMTP服务器的主机名。

JDBC数据源

0.简介

许多Web应用程序需要通过JDBC驱动程序访问数据库,以支持该应用程序所需的功能。Java EE平台规范要求Java EE Application Server 为此目的提供DataSource实现(即JDBC连接的连接池)。Tomcat提供完全相同的支持,因此使用此服务在Tomcat上开发的基于数据库的应用程序将在任何Java EE服务器上保持不变。

有关JDBC的信息,请参阅以下内容:

 - Tomcat中的默认数据源支持基于Commons 项目的DBCP 2连接池 。然而,也可以使用实现任何其他连接池,通过编写自己的自定义资源工厂,描述 如下javax.sql.DataSource

1.安装JDBC驱动程序

使用JDBC数据源 JNDI资源工厂要求您为Tomcat内部类和Web应用程序提供适当的JDBC驱动程序。通过将驱动程序的JAR文件安装到$CATALINA_HOME/lib目录中可以很容易地实现这一点 ,这使得驱动程序既可用于资源工厂,也可用于应用程序。

2.声明您的资源要求

接下来,修改Web应用程序部署描述符(/WEB-INF/web.xml)以声明JNDI名称,在该名称下将查找预配置的数据源。按照惯例,所有这些名称都应该解析为jdbc子上下文(相对于作为java:comp/env所有提供的资源工厂的根的标准命名上下文。典型的web.xml条目可能如下所示:

<resource-ref>
  <description>
    Resource reference to a factory for java.sql.Connection
    instances that may be used for talking to a particular
    database that is configured in the <Context>
    configuration for the web application.
  </description>
  <res-ref-name>
    jdbc/EmployeeDB
  </res-ref-name>
  <res-type>
    javax.sql.DataSource
  </res-type>
  <res-auth>
    Container
  </res-auth>
</resource-ref>

警告 - 请确保遵守DTD对Web应用程序部署描述符所要求的元素排序!有关详细信息,请参阅 Servlet规范

3.编写应用程序对此资源的使用

此资源引用的典型用法可能如下所示:

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
  envCtx.lookup("jdbc/EmployeeDB");

Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();

请注意,应用程序使用在Web应用程序部署描述符中声明的相同资源引用名称。这与<Context>在Web应用程序的元素中配置的资源工厂相匹配, 如下所述。

4.配置Tomcat的资源工厂

要配置Tomcat的资源工厂,请将类似这样的<Context>元素添加到Web应用程序的 元素中。

<Context ...>
  ...
  <Resource name="jdbc/EmployeeDB"
            auth="Container"
            type="javax.sql.DataSource"
            username="dbusername"
            password="dbpassword"
            driverClassName="org.hsql.jdbcDriver"
            url="jdbc:HypersonicSQL:database"
            maxTotal="8"
            maxIdle="4"/>
  ...
</Context>

请注意,资源名称(此处jdbc/EmployeeDB)必须与Web应用程序部署描述符中指定的值匹配。

此示例假定您使用的是HypersonicSQL数据库JDBC驱动程序。自定义driverClassName和 driverName参数以匹配实际数据库的JDBC驱动程序和连接URL。

Tomcat的标准数据源资源工厂(org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory)的配置属性如下:

  • driverClassName - 要使用的JDBC驱动程序的标准Java类名。
  • username - 要传递给JDBC驱动程序的数据库用户名。
  • password - 要传递给JDBC驱动程序的数据库密码。
  • url - 要传递给JDBC驱动程序的连接URL。(为了向后兼容,该属性driverName 也被识别。)
  • initialSize - 池初始化期间将在池中创建的初始连接数。默认值:0
  • maxTotal - 可以同时从此池分配的最大连接数。默认值:8
  • minIdle - 同时在此池中空闲的最小连接数。默认值:0
  • maxIdle - 可以同时在此池中空闲的最大连接数。默认值:8
  • maxWaitMillis - 在抛出异常之前,池将等待(没有可用连接时)连接的最大毫秒数。默认值:-1(无限)

一些其他属性处理连接验证:

  • validationQuery - 池可用于在连接返回应用程序之前验证连接的SQL查询。如果指定,则此查询必须是返回至少一行的SQL SELECT语句。
  • validationQueryTimeout - 要返回的验证查询的超时(以秒为单位)。默认值:-1(无限)
  • testOnBorrow - true或false:每次从池中借用验证查询时是否应验证连接。默认值:true
  • testOnReturn - true或false:每次将连接返回池时是否应使用验证查询验证连接。默认值:false

可选的逐出器线程负责通过删除长时间空闲的任何连接来缩小池。推销员不尊重minIdle。请注意,如果您只希望池根据配置的maxIdle属性收缩,则无需激活evictor线程。

默认情况下禁用逐出器,可以使用以下属性进行配置:

  • timeBetweenEvictionRunsMillis - 连续运行逐出器之间的毫秒数。默认值:-1(已禁用)
  • numTestsPerEvictionRun - 每次运行逐出器期间由逐出器检查空闲的连接数。默认值:3
  • minEvictableIdleTimeMillis - 清除程序之后可以从池中删除连接的空闲时间(以毫秒为单位)。默认值:30 * 60 * 1000(30分钟)
  • testWhileIdle - true或false:在池中空闲时,是否应使用验证程序线程使用验证查询验证连接。默认值:false

另一个可选功能是删除废弃的连接。如果应用程序长时间未将其返回池中,则称该连接被放弃。池可以自动关闭此类连接并将其从池中删除。这是泄漏连接的应用程序的解决方法。

默认情况下禁用放弃功能,可以使用以下属性进行配置:

  • removeAbandonedOnBorrow - true或false:是否在借用连接时从池中删除已放弃的连接。默认值:false
  • removeAbandonedOnMaintenance - true或false:是否在池维护期间从池中删除已放弃的连接。默认值:false
  • removeAbandonedTimeout - 假定借用连接被放弃的秒数。默认值:300
  • logAbandoned - true或false:是否记录放弃语句或连接的应用程序代码的堆栈跟踪。这增加了严重的开销。默认值:false

最后,有各种属性可以进一步微调池行为:

  • defaultAutoCommit - true或false:此池创建的连接的默认自动提交状态。默认值:true
  • defaultReadOnly - true或false:此池创建的连接的默认只读状态。默认值:false
  • defaultTransactionIsolation - 设置默认事务隔离级别。可以是一个 NONEREAD_COMMITTED, READ_UNCOMMITTEDREPEATABLE_READSERIALIZABLE。默认值:无默认设置
  • poolPreparedStatements - true或false:是否汇集PreparedStatements和CallableStatements。默认值:false
  • maxOpenPreparedStatements - 可以同时从语句池分配的最大打开语句数。默认值:-1(无限制)
  • defaultCatalog - 默认目录的名称。默认值:未设置
  • connectionInitSqls - 创建Connection后运行一次的SQL语句列表。用分号(;)分隔多个语句。默认值:无声明
  • connectionProperties - 传递给驱动程序以创建连接的驱动程序特定属性的列表。每个属性都给出name=value,多个属性由分号(;)分隔。默认值:无属性
  • accessToUnderlyingConnectionAllowed - true或false:是否允许访问底层连接。默认值:false

有关更多详细信息,请参阅Commons DBCP 2文档。

添加自定义资源工厂

如果没有标准资源工厂满足您的需求,您可以编写自己的工厂并将其集成到Tomcat中,然后<Context>在Web应用程序的元素中配置此工厂的使用 。在下面的示例中,我们将创建一个只知道如何com.mycompany.MyBean从上面的Generic JavaBean Resources示例创建bean 的工厂。

1.编写资源工厂类

您必须编写一个实现JNDI服务提供程序 javax.naming.spi.ObjectFactory接口的类。每次Web应用程序调用lookup()绑定到此工厂的上下文条目时(假设已配置工厂 singleton="false"),将getObjectInstance()使用以下参数调用该 方法:

  • Object obj - 包含可用于创建对象的位置或引用信息的(可能为null)对象。对于Tomcat,它始终是一个类型的对象 javax.naming.Reference,它包含此工厂类的类名,以及<Context>用于创建要返回的对象的配置属性(来自 Web应用程序)。
  • 名称名称 - 此工厂相对于其绑定的名称nameCtx,或者null未指定名称的名称。
  • Context nameCtx - name指定参数的上下文 ,或者null是否 name相对于默认初始上下文。
  • Hashtable环境 - 用于创建此对象的(可能为null)环境。这通常在Tomcat对象工厂中被忽略。

要创建一个知道如何生成MyBean 实例的资源工厂,您可以创建一个这样的类:

package com.mycompany;

import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

public class MyBeanFactory implements ObjectFactory {

  public Object getObjectInstance(Object obj,
      Name name2, Context nameCtx, Hashtable environment)
      throws NamingException {

      // Acquire an instance of our specified bean class
      MyBean bean = new MyBean();

      // Customize the bean properties from our attributes
      Reference ref = (Reference) obj;
      Enumeration addrs = ref.getAll();
      while (addrs.hasMoreElements()) {
          RefAddr addr = (RefAddr) addrs.nextElement();
          String name = addr.getType();
          String value = (String) addr.getContent();
          if (name.equals("foo")) {
              bean.setFoo(value);
          } else if (name.equals("bar")) {
              try {
                  bean.setBar(Integer.parseInt(value));
              } catch (NumberFormatException e) {
                  throw new NamingException("Invalid 'bar' value " + value);
              }
          }
      }

      // Return the customized instance
      return (bean);

  }

}

在此示例中,我们无条件地创建类的新实例com.mycompany.MyBean,并根据<ResourceParams> 配置此工厂的元素中包含的参数填充其属性(请参见下文)。您应该注意,factory应该跳过任何名为的参数- 该参数用于指定工厂类本身的名称(在本例中为 com.mycompany.MyBeanFactory),而不是正在配置的bean的属性。

有关更多信息ObjectFactory,请参阅 JNDI服务提供程序接口(SPI)规范

您需要针对包含目录中所有JAR文件的类路径编译此类$CATALINA_HOME/lib。完成后,将工厂类(和相应的bean类)解压缩到其下 $CATALINA_HOME/lib,或放在JAR文件中 $CATALINA_HOME/lib。这样,Catalina内部资源和Web应用程序都可以看到所需的类文件。

2.声明您的资源要求

接下来,修改Web应用程序部署描述符(/WEB-INF/web.xml)以声明JNDI名称,在该名称下将请求此Bean的新实例。最简单的方法是使用一个<resource-env-ref>元素,如下所示:

<resource-env-ref>
  <description>
    Object factory for MyBean instances.
  </description>
  <resource-env-ref-name>
    bean/MyBeanFactory
  </resource-env-ref-name>
  <resource-env-ref-type>
    com.mycompany.MyBean
  </resource-env-ref-type>
</resource-env-ref>

警告 - 请确保遵守DTD对Web应用程序部署描述符所要求的元素排序!有关详细信息,请参阅 Servlet规范

3.编写应用程序对此资源的使用

此资源环境引用的典型用法可能如下所示:

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");

writer.println("foo = " + bean.getFoo() + ", bar = " +
               bean.getBar());

4.配置Tomcat的资源工厂

要配置Tomcat的资源工厂,请将此类元素添加<Context>到此Web应用程序的 元素中。

<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean"
            factory="com.mycompany.MyBeanFactory"
            singleton="false"
            bar="23"/>
  ...
</Context>

请注意,资源名称(此处bean/MyBeanFactory 必须与Web应用程序部署描述符中指定的值匹配。我们还初始化bar 属性的值,这将导致setBar(23)在返回新bean之前调用。因为我们没有初始化 foo属性(虽然我们可以),bean将包含其构造函数设置的任何默认值。

您还将注意到,从应用程序开发人员的角度来看,资源环境引用的声明以及用于请求新实例的编程与用于Generic JavaBean Resources示例的方法相同 。这说明了使用JNDI资源封装功能的一个优点 - 您可以更改底层实现,而无需使用资源修改应用程序,只要您维护兼容的API即可。

 

转载来源:https://tomcat.apache.org/tomcat-9.0-doc/index.html

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐