1
.
配置系统管理(
Admin Web Application
)
大多数商业化的 J2EE 服务器都提供一个功能强大的管理界面,且大都采用易于理解的 Web 应用界面。 Tomcat 按照自己的方式,同样提供一个成熟的管理工具,并且丝毫不逊于那些商业化的竞争对手。 Tomcat 的 Admin Web Application 最初在 4.1 版本时出现,当时的功能包括管理 context 、 data source 、 user 和 group 等。当然也可以管理像初始化参数, user 、 group 、 role 的多种数据库管理等。在后续的版本中,这些功能将得到很大的扩展,但现有的功能已经非常实用了。
Admin Web Application 被定义在自动部署文件: CATALINA_BASE/webapps/admin.xml 。
(译者注: CATALINA_BASE 即 tomcat 安装目录下的 server 目录)
你必须编辑这个文件,以确定 Context 中的 docBase 参数是绝对路径。也就是说, CATALINA_BASE/webapps/admin.xml 的路径是绝对路径。作为另外一种选择,你也可以删除这个自动部署文件,而在 server.xml 文件中建立一个 Admin Web Application 的 context ,效果是一样的。你不能管理 Admin Web Application 这个应用,换而言之,除了删除 CATALINA_BASE/webapps/admin.xml ,你可能什么都做不了。
如果你使用 UserDatabaseRealm (默认),你将需要添加一个 user 以及一个 role 到 CATALINA_BASE/conf/tomcat-users.xml 文件中。你编辑这个文件,添加一个名叫 “admin” 的 role 到该文件中,如下:
<role name="admin"/>
你同样需要有一个用户,并且飧鲇没 У 慕巧 恰癮 dmin” 。象存在的用户那样,添加一个用户(改变密码使其更加安全):
<user name="admin" password="deep_dark_secret" roles="admin"/>
当你完成这些步骤后,请重新启动 Tomcat ,访问 http://localhost:8080/admin ,你将看到一个登录界面。 Admin Web Application 采用基于容器管理的安全机制,并采用了 Jakarta Struts 框架。一旦你作为 “admin” 角色的用户登录管理界面,你将能够使用这个管理界面配置 Tomcat 。
2 .配置应用管理( Manager Web Application )
Manager Web Application 让你通过一个比 Admin Web Application 更为简单的用户界面,执行一些简单的 Web 应用任务。
Manager Web Application 被被定义在一个自动部署文件中:
CATALINA_BASE/webapps/manager.xml 。
你必须编辑这个文件,以确保 context 的 docBase 参数是绝对路径,也就是说 CATALINA_HOME/server/webapps/manager 的绝对路径。
(译者注: CATALINA_HOME 即 tomcat 安装目录)
如果你使用的是 UserDatabaseRealm ,那么你需要添加一个角色和一个用户到 CATALINA_BASE/conf/tomcat-users.xml 文件中。接下来,编辑这个文件,添加一个名为 “manager” 的角色到该文件中:
<role name=”manager”>
你同样需要有一个角色为 “manager” 的用户。像已经存在的用户那样,添加一个新用户(改变密码使其更加安全):
<user name="manager" password="deep_dark_secret" roles="manager"/>
然后重新启动 Tomcat ,访问 http://localhost/manager/list ,将看到一个很朴素的文本型管理界面,或者访问 http: //localhost/manager/html/list ,将看到一个 HMTL 的管理界面。不管是哪种方式都说明你的 Manager Web Application 现在已经启动了。
Manager application 让你可以在没有系统管理特权的基础上,安装新的 Web 应用,以用于测试。如果我们有一个新的 web 应用位于 /home/user/hello 下在,并且想把它安装到 /hello 下,为了测试这个应用,我们可以这么做,在第一个文件框中输入 “/hello” (作为访问时的 path ),在第二个文本框中输入 “file: /home/user/hello” (作为 Config URL )。
Manager application 还允许你停止、重新启动、移除以及重新部署一个 web 应用。停止一个应用使其无法被访问,当有用户尝试访问这个被停止的应用时,将看到一个 503 的错误 ——“503 - This application is not currently available” 。
移除一个 web 应用,只是指从 Tomcat 的运行拷贝中删除了该应用,如果你重新启动 Tomcat ,被删除的应用将再次出现(也就是说,移除并不是指从硬盘上删除)。
3 .部署一个 web 应用
有两个办法可以在系统中部署 web 服务。
1> 拷贝你的 WAR 文件或者你的 web 应用文件夹(包括该 web 的所有内容)到 $CATALINA_BASE/webapps 目录下。
2> 为你的 web 服务建立一个只包括 context 内容的 XML 片断文件,并把该文件放到 $CATALINA_BASE/webapps 目录下。这个 web 应用本身可以存储在硬盘上的任何地方。
如果你有一个 WAR 文件,你若想部署它,则只需要把该文件简单的拷贝到 CATALINA_BASE/webapps 目录下即可,文件必须以 “.war” 作为扩展名。一旦 Tomcat 监听到这个文件,它将(缺省的)解开该文件包作为一个子目录,并以 WAR 文件的文件名作为子目录的名字。接下来, Tomcat 将在内存中建立一个 context ,就好象你在 server.xml 文件里建立一样。当然,其他必需的内容,将从 server.xml 中的 DefaultContext 获得。
部署 web 应用的另一种方式是写一个 Context XML 片断文件,然后把该文件拷贝到 CATALINA_BASE/webapps 目录下。一个 Context 片断并非一个完整的 XML 文件,而只是一个 context 元素,以及对该应用的相应描述。这种片断文件就像是从 server.xml 中切取出来的 context 元素一样,所以这种片断被命名为 “context 片断 ” 。
举个例子,如果我们想部署一个名叫 MyWebApp.war 的应用,该应用使用 realm 作为访问控制方式,我们可以使用下面这个片断:
<!--
Context fragment for deploying MyWebApp.war
-->
<Context path="/demo" docBase="webapps/MyWebApp.war"
debug="0" privileged="true">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Context>
把该片断命名为 “MyWebApp.xml” ,然后拷贝到 CATALINA_BASE/webapps 目录下。
这种 context 片断提供了一种便利的方法来部署 web 应用,你不需要编辑 server.xml ,除非你想改变缺省的部署特性,安装一个新的 web 应用时不需要重启动 Tomcat 。
4 .配置虚拟主机( Virtual Hosts )
关于 server.xml 中 “Host” 这个元素,只有在你设置虚拟主机的才需要修改。虚拟主机是一种在一个 web 服务器上服务多个域名的机制,对每个域名而言,都好象独享了整个主机。实际上,大多数的小型商务网站都是采用虚拟主机实现的,这主要是因为虚拟主机能直接连接到 Internet 并提供相应的带宽,以保障合理的访问响应速度,另外虚拟主机还能提供一个稳定的固定 IP 。
基于名字的虚拟主机可以被建立在任何 web 服务器上,建立的方法就是通过在域名服务器( DNS )上建立 IP 地址的别名,并且告诉 web 服务器把去往不同域名的请求分发到相应的网页目录。因为这篇文章主要是讲 Tomcat ,我们不准备介绍在各种操作系统上设置 DNS 的方法,如果你在这方面需要帮助,请参考《 DNS and Bind 》一书,作者是 Paul Albitz and Cricket Liu (O'Reilly) 。为了示范方便,我将使用一个静态的主机文件,因为这是测试别名最简单的方法。
在 Tomcat 中使用虚拟主机,你需要设置 DNS 或主机数据。为了测试,为本地 IP 设置一个 IP 别名就足够了,接下来,你需要在 server.xml 中添加几行内容,如下:
<Server port="8005" shutdown="SHUTDOWN" debug="0">
<Service name="Tomcat-Standalone">
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8080" minProcessors="5" maxProcessors="75"
enableLookups="true" redirectPort="8443"/>
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8443" minProcessors="5" maxProcessors="75"
acceptCount="10" debug="0" scheme="https" secure="true"/>
<Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory"
clientAuth="false" protocol="TLS" />
</Connector>
<Engine name="Standalone" defaultHost="localhost" debug="0">
<!-- This Host is the default Host -->
<Host name="localhost" debug="0" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="" docBase="ROOT" debug="0"/>
<Context path="/orders" docBase="/home/ian/orders" debug="0"
reloadable="true" crossContext="true">
</Context>
</Host>
<!-- This Host is the first "Virtual Host": www.example.com -->
<Host name="www.example.com" appBase="/home/example/webapp">
<Context path="" docBase="."/>
</Host>
</Engine>
</Service>
</Server>
Tomcat 的 server.xml 文件,在初始状态下,只包括一个虚拟主机,但是它容易被扩充到支持多个虚拟主机。在前面的例子中展示的是一个简单的 server.xml 版本,其中粗体部分就是用于添加一个虚拟主机。每一个 Host 元素必须包括一个或多个 context 元素,所包含的 context 元素中必须有一个是默认的 context ,这个默认的 context 的显示路径应该为空(例如, path=”” )。
5 .配置基础验证( Basic Authentication )
容器管理验证方法控制着当用户访问受保护的 web 应用资源时,如何进行用户的身份鉴别。当一个 web 应用使用了 Basic Authentication ( BASIC 参数在 web.xml 文件中 auto-method 元素中设置),而有用户访问受保护的 web 应用时, Tomcat 将通过 HTTP Basic Authentication 方式,弹出一个对话框,要求用户输入用户名和密码。在这种验证方法中,所有密码将被以 64 位的编码方式在网络上传输。
注意:使用 Basic Authentication 通过被认为是不安全的,因为它没有强健的加密方法,除非在客户端和服务器端都使用 HTTPS 或者其他密码加密码方式(比如,在一个虚拟私人网络中)。若没有额外的加密方法,网络管理员将能够截获(或滥用)用户的密码。但是,如果你是刚开始使用 Tomcat ,或者你想在你的 web 应用中测试一下基于容器的安全管理, Basic Authentication 还是非常易于设置和使用的。只需要添加 <security-constraint> 和 <login- config> 两个元素到你的 web 应用的 web.xml 文件中,并且在 CATALINA_BASE/conf/tomcat-users.xml 文件中添加适当的 <role> 和 <user> 即可,然后重新启动 Tomcat 。
下面例子中的 web.xml 摘自一个俱乐部会员网站系统,该系统中只有 member 目录被保护起来,并使用 Basic Authentication 进行身份验证。请注意,这种方式将有效的代替 Apache web 服务器中的 .htaccess 文件。
<!--
Define the Members-only area, by defining
a "Security Constraint" on this Application, and
mapping it to the subdirectory (URL) that we want
to restrict.
-->
<security-constraint>
<web-resource-collection>
<web-resource-name>
Entire Application
</web-resource-name>
<url-pattern>/members/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>member</role-name>
</auth-constraint>
</security-constraint>
<!-- Define the Login Configuration for this Application -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>My Club Members-only Area</realm-name>
</login-config>
6 .配置单点登录( Single Sign-On )
一旦你设置了 realm 和验证的方法,你就需要进行实际的用户登录处理。一般说来,对用户而言登录系统是一件很麻烦的事情,你必须尽量减少用户登录验证的次数。作为缺省的情况,当用户第一次请求受保护的资源时,每一个 web 应用都会要求用户登录。如果你运行了多个 web 应用,并且每个应用都需要进行单独的用户验证,那这看起来就有点像你在与你的用户搏斗。用户们不知道怎样才能把多个分离的应用整合成一个单独的系统,所有他们也就不知道他们需要访问多少个不同的应用,只是很迷惑,为什么总要不停的登录。
Tomcat 4 的 “single sign-on” 特性允许用户在访问同一虚拟主机下所有 web 应用时,只需登录一次。为了使用这个功能,你只需要在 Host 上添加一个 SingleSignOn Valve 元素即可,如下所示:
<Valve className="org.apache.catalina.authenticator.SingleSignOn"
debug="0"/>
在 Tomcat 初始安装后, server.xml 的注释里面包括 SingleSignOn Valve 配置的例子,你只需要去掉注释,即可使用。那么,任何用户只要登录过一个应用,则对于同一虚拟主机下的所有应用同样有效。
使用 single sign-on valve 有一些重要的限制:
1> value 必须被配置和嵌套在相同的 Host 元素里,并且所有需要进行单点验证的 web 应用(必须通过 context 元素定义)都位于该 Host 下。
2> 包括共享用户信息的 realm 必须被设置在同一级 Host 中或者嵌套之外。
3> 不能被 context 中的 realm 覆盖。
4> 使用单点登录的 web 应用最好使用一个 Tomcat 的内置的验证方式(被定义在 web.xml 中的 <auth-method> 中),这比自定义的验证方式强, Tomcat 内置的的验证方式包括 basic 、 digest 、 form 和 client-cert 。
5> 如果你使用单点登录,还希望集成一个第三方的 web 应用到你的网站中来,并且这个新的 web 应用使用它自己的验证方式,而不使用容器管理安全,那你基本上就没招了。你的用户每次登录原来所有应用时需要登录一次,并且在请求新的第三方应用时还得再登录一次。当然,如果你拥有这个第三方 web 应用的源码,而你又是一个程序员,你可以修改它,但那恐怕也不容易做。
6> 单点登录需要使用 cookies 。
7 .配置用户定制目录( Customized User Directores )
一些站点允许个别用户在服务器上发布网页。例如,一所大学的学院可能想给每一位学生一个公共区域,或者是一个 ISP 希望给一些 web 空间给他的客户,但这又不是虚拟主机。在这种情况下,一个典型的方法就是在用户名前面加一个特殊字符( ~ ),作为每位用户的网站,比如:
http://www.cs.myuniversity.edu/~username
http://members.mybigisp.com/~username
Tomcat 提供两种方法在主机上映射这些个人网站,主要使用一对特殊的 Listener 元素。 Listener 的 className 属性应该是 org.apache.catalina.startup.UserConfig , userClass 属性应该是几个映射类之一。如果你的系统是 Unix ,它将有一个标准的 /etc/passwd 文件,该文件中的帐号能够被运行中的 Tomcat 很容易的读取,该文件指定了用户的主目录,使用 PasswdUserDatabase 映射类。
<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html"
userClass="org.apache.catalina.startup.PasswdUserDatabase"/>
web 文件需要放置在像 /home/users/ian/public_html 或者 /users/jbrittain/public_html 一样的目录下面。当然你也可以改变 public_html 到其他任何子目录下。
实际上,这个用户目录根本不一定需要位于用户主目录下里面。如果你没有一个密码文件,但你又想把一个用户名映射到公共的像 /home 一样目录的子目录里面,则可以使用 HomesUserDatabase 类。
<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html" homeBase="/home"
userClass="org.apache.catalina.startup.HomesUserDatabase"/>
这样一来, web 文件就可以位于像 /home/ian/public_html 或者 /home/jasonb/public_html 一样的目录下。这种形式对 Windows 而言更加有利,你可以使用一个像 c:/home 这样的目录。
这些 Listener 元素,如果出现,则必须在 Host 元素里面,而不能在 context 元素里面,因为它们都用应用于 Host 本身。
8 .在 Tomcat 中使用 CGI 脚本
Tomcat 主要是作为 Servlet/JSP 容器,但它也有许多传统 web 服务器的性能。支持通用网关接口( Common Gateway Interface ,即 CGI )就是其中之一, CGI 提供一组方法在响应浏览器请求时运行一些扩展程序。 CGI 之所以被称为通用,是因为它能在大多数程序或脚本中被调用,包括: Perl , Python , awk , Unix shell scripting 等,甚至包括 Java 。当然,你大概不会把一个 Java 应用程序当作 CGI 来运行,毕竟这样太过原始。一般而言,开发 Servlet 总要比 CGI 具有更好的效率,因为当用户点击一个链接或一个按钮时,你不需要从操作系统层开始进行处理。
Tomcat 包括一个可选的 CGI Servlet ,允许你运行遗留下来的 CGI 脚本。
为了使 Tomcat 能够运行 CGI ,你必须做如下几件事:
1. 把 servlets-cgi.renametojar (在 CATALINA_HOME/server/lib/ 目录下)改名为 servlets-cgi.jar 。处理 CGI 的 servlet 应该位于 Tomcat 的 CLASSPATH 下。
2. 在 Tomcat 的 CATALINA_BASE/conf/web.xml 文件中,把关于 <servlet-name> CGI 的那段的注释去掉(默认情况下,该段位于第 241 行)。
3. 同样,在 Tomcat 的 CATALINA_BASE/conf/web.xml 文件中,把关于对 CGI 进行映射的那段的注释去掉(默认情况下,该段位于第 299 行)。注意,这段内容指定了 HTML 链接到 CGI 脚本的访问方式。
4. 你可以把 CGI 脚本放置在 WEB-INF/cgi 目录下(注意, WEB-INF 是一个安全的地方,你可以把一些不想被用户看见或基于安全考虑不想暴露的文件放在此处),或者你也可以把 CGI 脚本放置在 context 下的其他目录下,并为 CGI Servlet 调整 cgiPathPrefix 初始化参数。这就指定的 CGI Servlet 的实际位置,且不能与上一步指定的 URL 重名。
5. 重新启动 Tomcat ,你的 CGI 就可以运行了。
在 Tomcat 中, CGI 程序缺省放置在 WEB-INF/cgi 目录下,正如前面所提示的那样, WEB-INF 目录受保护的,通过客户端的浏览器无法窥探到其中内容,所以对于放置含有密码或其他敏感信息的 CGI 脚本而言,这是一个非常好的地方。为了兼容其他服务器,尽管你也可以把 CGI 脚本保存在传统的 /cgi-bin 目录,但要知道,在这些目录中的文件有可能被网上好奇的冲浪者看到。另外,在 Unix 中,请确定运行 Tomcat 的用户有执行 CGI 脚本的权限。
9 .改变 Tomcat 中的 JSP 编译器( JSP Compiler )
在 Tomcat 4.1 (或更高版本,大概), JSP 的编译由包含在 Tomcat 里面的 Ant 程序控制器直接执行。这听起来有一点点奇怪,但这正是 Ant 有意为之的一部分,有一个 API 文档指导开发者在没有启动一个新的 JVM 的情况下,使用 Ant 。这是使用 Ant 进行 Java 开发的一大优势。另外,这也意味着你现在能够在 Ant 中使用任何 javac 支持的编译方式,这里有一个关于 Apache Ant 使用手册的 javac page 列表。使用起来是容易的,因为你只需要在 <init-param> 元素中定义一个名字叫 “compiler” ,并且在 value 中有一个支持编译的编译器名字,示例如下:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>
org.apache.jasper.servlet.JspServlet
</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>WARNING</param-value>
</init-param>
<init-param>
<param-name>compiler</param-name>
<param-value>jikes</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
当然,给出的编译器必须已经安装在你的系统中,并且 CLASSPATH 可能需要设置,那处决于你选择的是何种编译器。
10 .限制特定主机访问( Restricting Access to Specific Hosts )
有时,你可能想限制对 Tomcat web 应用的访问,比如,你希望只有你指定的主机或 IP 地址可以访问你的应用。这样一来,就只有那些指定的的客户端可以访问服务的内容了。为了实现这种效果, Tomcat 提供了两个参数供你配置: RemoteHostValve 和 RemoteAddrValve 。
通过配置这两个参数,可以让你过滤来自请求的主机或 IP 地址,并允许或拒绝哪些主机 /IP 。与之类似的,在 Apache 的 httpd 文件里有对每个目录的允许 / 拒绝指定。
例如你可以把 Admin Web application 设置成只允许本地访问,设置如下:
<Context path="/path/to/secret_files" ...>
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.0.0.1" deny=""/>
</Context>
如果没有给出允许主机的指定,那么与拒绝主机匹配的主机就会被拒绝,除此之外的都是允许的。与之类似,如果没有给出拒绝主机的指定,那么与允许主机匹配的主机就会被允许,除此之外的都是拒绝的。
大多数商业化的 J2EE 服务器都提供一个功能强大的管理界面,且大都采用易于理解的 Web 应用界面。 Tomcat 按照自己的方式,同样提供一个成熟的管理工具,并且丝毫不逊于那些商业化的竞争对手。 Tomcat 的 Admin Web Application 最初在 4.1 版本时出现,当时的功能包括管理 context 、 data source 、 user 和 group 等。当然也可以管理像初始化参数, user 、 group 、 role 的多种数据库管理等。在后续的版本中,这些功能将得到很大的扩展,但现有的功能已经非常实用了。
Admin Web Application 被定义在自动部署文件: CATALINA_BASE/webapps/admin.xml 。
(译者注: CATALINA_BASE 即 tomcat 安装目录下的 server 目录)
你必须编辑这个文件,以确定 Context 中的 docBase 参数是绝对路径。也就是说, CATALINA_BASE/webapps/admin.xml 的路径是绝对路径。作为另外一种选择,你也可以删除这个自动部署文件,而在 server.xml 文件中建立一个 Admin Web Application 的 context ,效果是一样的。你不能管理 Admin Web Application 这个应用,换而言之,除了删除 CATALINA_BASE/webapps/admin.xml ,你可能什么都做不了。
如果你使用 UserDatabaseRealm (默认),你将需要添加一个 user 以及一个 role 到 CATALINA_BASE/conf/tomcat-users.xml 文件中。你编辑这个文件,添加一个名叫 “admin” 的 role 到该文件中,如下:
<role name="admin"/>
你同样需要有一个用户,并且飧鲇没 У 慕巧 恰癮 dmin” 。象存在的用户那样,添加一个用户(改变密码使其更加安全):
<user name="admin" password="deep_dark_secret" roles="admin"/>
当你完成这些步骤后,请重新启动 Tomcat ,访问 http://localhost:8080/admin ,你将看到一个登录界面。 Admin Web Application 采用基于容器管理的安全机制,并采用了 Jakarta Struts 框架。一旦你作为 “admin” 角色的用户登录管理界面,你将能够使用这个管理界面配置 Tomcat 。
2 .配置应用管理( Manager Web Application )
Manager Web Application 让你通过一个比 Admin Web Application 更为简单的用户界面,执行一些简单的 Web 应用任务。
Manager Web Application 被被定义在一个自动部署文件中:
CATALINA_BASE/webapps/manager.xml 。
你必须编辑这个文件,以确保 context 的 docBase 参数是绝对路径,也就是说 CATALINA_HOME/server/webapps/manager 的绝对路径。
(译者注: CATALINA_HOME 即 tomcat 安装目录)
如果你使用的是 UserDatabaseRealm ,那么你需要添加一个角色和一个用户到 CATALINA_BASE/conf/tomcat-users.xml 文件中。接下来,编辑这个文件,添加一个名为 “manager” 的角色到该文件中:
<role name=”manager”>
你同样需要有一个角色为 “manager” 的用户。像已经存在的用户那样,添加一个新用户(改变密码使其更加安全):
<user name="manager" password="deep_dark_secret" roles="manager"/>
然后重新启动 Tomcat ,访问 http://localhost/manager/list ,将看到一个很朴素的文本型管理界面,或者访问 http: //localhost/manager/html/list ,将看到一个 HMTL 的管理界面。不管是哪种方式都说明你的 Manager Web Application 现在已经启动了。
Manager application 让你可以在没有系统管理特权的基础上,安装新的 Web 应用,以用于测试。如果我们有一个新的 web 应用位于 /home/user/hello 下在,并且想把它安装到 /hello 下,为了测试这个应用,我们可以这么做,在第一个文件框中输入 “/hello” (作为访问时的 path ),在第二个文本框中输入 “file: /home/user/hello” (作为 Config URL )。
Manager application 还允许你停止、重新启动、移除以及重新部署一个 web 应用。停止一个应用使其无法被访问,当有用户尝试访问这个被停止的应用时,将看到一个 503 的错误 ——“503 - This application is not currently available” 。
移除一个 web 应用,只是指从 Tomcat 的运行拷贝中删除了该应用,如果你重新启动 Tomcat ,被删除的应用将再次出现(也就是说,移除并不是指从硬盘上删除)。
3 .部署一个 web 应用
有两个办法可以在系统中部署 web 服务。
1> 拷贝你的 WAR 文件或者你的 web 应用文件夹(包括该 web 的所有内容)到 $CATALINA_BASE/webapps 目录下。
2> 为你的 web 服务建立一个只包括 context 内容的 XML 片断文件,并把该文件放到 $CATALINA_BASE/webapps 目录下。这个 web 应用本身可以存储在硬盘上的任何地方。
如果你有一个 WAR 文件,你若想部署它,则只需要把该文件简单的拷贝到 CATALINA_BASE/webapps 目录下即可,文件必须以 “.war” 作为扩展名。一旦 Tomcat 监听到这个文件,它将(缺省的)解开该文件包作为一个子目录,并以 WAR 文件的文件名作为子目录的名字。接下来, Tomcat 将在内存中建立一个 context ,就好象你在 server.xml 文件里建立一样。当然,其他必需的内容,将从 server.xml 中的 DefaultContext 获得。
部署 web 应用的另一种方式是写一个 Context XML 片断文件,然后把该文件拷贝到 CATALINA_BASE/webapps 目录下。一个 Context 片断并非一个完整的 XML 文件,而只是一个 context 元素,以及对该应用的相应描述。这种片断文件就像是从 server.xml 中切取出来的 context 元素一样,所以这种片断被命名为 “context 片断 ” 。
举个例子,如果我们想部署一个名叫 MyWebApp.war 的应用,该应用使用 realm 作为访问控制方式,我们可以使用下面这个片断:
<!--
Context fragment for deploying MyWebApp.war
-->
<Context path="/demo" docBase="webapps/MyWebApp.war"
debug="0" privileged="true">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Context>
把该片断命名为 “MyWebApp.xml” ,然后拷贝到 CATALINA_BASE/webapps 目录下。
这种 context 片断提供了一种便利的方法来部署 web 应用,你不需要编辑 server.xml ,除非你想改变缺省的部署特性,安装一个新的 web 应用时不需要重启动 Tomcat 。
4 .配置虚拟主机( Virtual Hosts )
关于 server.xml 中 “Host” 这个元素,只有在你设置虚拟主机的才需要修改。虚拟主机是一种在一个 web 服务器上服务多个域名的机制,对每个域名而言,都好象独享了整个主机。实际上,大多数的小型商务网站都是采用虚拟主机实现的,这主要是因为虚拟主机能直接连接到 Internet 并提供相应的带宽,以保障合理的访问响应速度,另外虚拟主机还能提供一个稳定的固定 IP 。
基于名字的虚拟主机可以被建立在任何 web 服务器上,建立的方法就是通过在域名服务器( DNS )上建立 IP 地址的别名,并且告诉 web 服务器把去往不同域名的请求分发到相应的网页目录。因为这篇文章主要是讲 Tomcat ,我们不准备介绍在各种操作系统上设置 DNS 的方法,如果你在这方面需要帮助,请参考《 DNS and Bind 》一书,作者是 Paul Albitz and Cricket Liu (O'Reilly) 。为了示范方便,我将使用一个静态的主机文件,因为这是测试别名最简单的方法。
在 Tomcat 中使用虚拟主机,你需要设置 DNS 或主机数据。为了测试,为本地 IP 设置一个 IP 别名就足够了,接下来,你需要在 server.xml 中添加几行内容,如下:
<Server port="8005" shutdown="SHUTDOWN" debug="0">
<Service name="Tomcat-Standalone">
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8080" minProcessors="5" maxProcessors="75"
enableLookups="true" redirectPort="8443"/>
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8443" minProcessors="5" maxProcessors="75"
acceptCount="10" debug="0" scheme="https" secure="true"/>
<Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory"
clientAuth="false" protocol="TLS" />
</Connector>
<Engine name="Standalone" defaultHost="localhost" debug="0">
<!-- This Host is the default Host -->
<Host name="localhost" debug="0" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="" docBase="ROOT" debug="0"/>
<Context path="/orders" docBase="/home/ian/orders" debug="0"
reloadable="true" crossContext="true">
</Context>
</Host>
<!-- This Host is the first "Virtual Host": www.example.com -->
<Host name="www.example.com" appBase="/home/example/webapp">
<Context path="" docBase="."/>
</Host>
</Engine>
</Service>
</Server>
Tomcat 的 server.xml 文件,在初始状态下,只包括一个虚拟主机,但是它容易被扩充到支持多个虚拟主机。在前面的例子中展示的是一个简单的 server.xml 版本,其中粗体部分就是用于添加一个虚拟主机。每一个 Host 元素必须包括一个或多个 context 元素,所包含的 context 元素中必须有一个是默认的 context ,这个默认的 context 的显示路径应该为空(例如, path=”” )。
5 .配置基础验证( Basic Authentication )
容器管理验证方法控制着当用户访问受保护的 web 应用资源时,如何进行用户的身份鉴别。当一个 web 应用使用了 Basic Authentication ( BASIC 参数在 web.xml 文件中 auto-method 元素中设置),而有用户访问受保护的 web 应用时, Tomcat 将通过 HTTP Basic Authentication 方式,弹出一个对话框,要求用户输入用户名和密码。在这种验证方法中,所有密码将被以 64 位的编码方式在网络上传输。
注意:使用 Basic Authentication 通过被认为是不安全的,因为它没有强健的加密方法,除非在客户端和服务器端都使用 HTTPS 或者其他密码加密码方式(比如,在一个虚拟私人网络中)。若没有额外的加密方法,网络管理员将能够截获(或滥用)用户的密码。但是,如果你是刚开始使用 Tomcat ,或者你想在你的 web 应用中测试一下基于容器的安全管理, Basic Authentication 还是非常易于设置和使用的。只需要添加 <security-constraint> 和 <login- config> 两个元素到你的 web 应用的 web.xml 文件中,并且在 CATALINA_BASE/conf/tomcat-users.xml 文件中添加适当的 <role> 和 <user> 即可,然后重新启动 Tomcat 。
下面例子中的 web.xml 摘自一个俱乐部会员网站系统,该系统中只有 member 目录被保护起来,并使用 Basic Authentication 进行身份验证。请注意,这种方式将有效的代替 Apache web 服务器中的 .htaccess 文件。
<!--
Define the Members-only area, by defining
a "Security Constraint" on this Application, and
mapping it to the subdirectory (URL) that we want
to restrict.
-->
<security-constraint>
<web-resource-collection>
<web-resource-name>
Entire Application
</web-resource-name>
<url-pattern>/members/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>member</role-name>
</auth-constraint>
</security-constraint>
<!-- Define the Login Configuration for this Application -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>My Club Members-only Area</realm-name>
</login-config>
6 .配置单点登录( Single Sign-On )
一旦你设置了 realm 和验证的方法,你就需要进行实际的用户登录处理。一般说来,对用户而言登录系统是一件很麻烦的事情,你必须尽量减少用户登录验证的次数。作为缺省的情况,当用户第一次请求受保护的资源时,每一个 web 应用都会要求用户登录。如果你运行了多个 web 应用,并且每个应用都需要进行单独的用户验证,那这看起来就有点像你在与你的用户搏斗。用户们不知道怎样才能把多个分离的应用整合成一个单独的系统,所有他们也就不知道他们需要访问多少个不同的应用,只是很迷惑,为什么总要不停的登录。
Tomcat 4 的 “single sign-on” 特性允许用户在访问同一虚拟主机下所有 web 应用时,只需登录一次。为了使用这个功能,你只需要在 Host 上添加一个 SingleSignOn Valve 元素即可,如下所示:
<Valve className="org.apache.catalina.authenticator.SingleSignOn"
debug="0"/>
在 Tomcat 初始安装后, server.xml 的注释里面包括 SingleSignOn Valve 配置的例子,你只需要去掉注释,即可使用。那么,任何用户只要登录过一个应用,则对于同一虚拟主机下的所有应用同样有效。
使用 single sign-on valve 有一些重要的限制:
1> value 必须被配置和嵌套在相同的 Host 元素里,并且所有需要进行单点验证的 web 应用(必须通过 context 元素定义)都位于该 Host 下。
2> 包括共享用户信息的 realm 必须被设置在同一级 Host 中或者嵌套之外。
3> 不能被 context 中的 realm 覆盖。
4> 使用单点登录的 web 应用最好使用一个 Tomcat 的内置的验证方式(被定义在 web.xml 中的 <auth-method> 中),这比自定义的验证方式强, Tomcat 内置的的验证方式包括 basic 、 digest 、 form 和 client-cert 。
5> 如果你使用单点登录,还希望集成一个第三方的 web 应用到你的网站中来,并且这个新的 web 应用使用它自己的验证方式,而不使用容器管理安全,那你基本上就没招了。你的用户每次登录原来所有应用时需要登录一次,并且在请求新的第三方应用时还得再登录一次。当然,如果你拥有这个第三方 web 应用的源码,而你又是一个程序员,你可以修改它,但那恐怕也不容易做。
6> 单点登录需要使用 cookies 。
7 .配置用户定制目录( Customized User Directores )
一些站点允许个别用户在服务器上发布网页。例如,一所大学的学院可能想给每一位学生一个公共区域,或者是一个 ISP 希望给一些 web 空间给他的客户,但这又不是虚拟主机。在这种情况下,一个典型的方法就是在用户名前面加一个特殊字符( ~ ),作为每位用户的网站,比如:
http://www.cs.myuniversity.edu/~username
http://members.mybigisp.com/~username
Tomcat 提供两种方法在主机上映射这些个人网站,主要使用一对特殊的 Listener 元素。 Listener 的 className 属性应该是 org.apache.catalina.startup.UserConfig , userClass 属性应该是几个映射类之一。如果你的系统是 Unix ,它将有一个标准的 /etc/passwd 文件,该文件中的帐号能够被运行中的 Tomcat 很容易的读取,该文件指定了用户的主目录,使用 PasswdUserDatabase 映射类。
<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html"
userClass="org.apache.catalina.startup.PasswdUserDatabase"/>
web 文件需要放置在像 /home/users/ian/public_html 或者 /users/jbrittain/public_html 一样的目录下面。当然你也可以改变 public_html 到其他任何子目录下。
实际上,这个用户目录根本不一定需要位于用户主目录下里面。如果你没有一个密码文件,但你又想把一个用户名映射到公共的像 /home 一样目录的子目录里面,则可以使用 HomesUserDatabase 类。
<Listener className="org.apache.catalina.startup.UserConfig"
directoryName="public_html" homeBase="/home"
userClass="org.apache.catalina.startup.HomesUserDatabase"/>
这样一来, web 文件就可以位于像 /home/ian/public_html 或者 /home/jasonb/public_html 一样的目录下。这种形式对 Windows 而言更加有利,你可以使用一个像 c:/home 这样的目录。
这些 Listener 元素,如果出现,则必须在 Host 元素里面,而不能在 context 元素里面,因为它们都用应用于 Host 本身。
8 .在 Tomcat 中使用 CGI 脚本
Tomcat 主要是作为 Servlet/JSP 容器,但它也有许多传统 web 服务器的性能。支持通用网关接口( Common Gateway Interface ,即 CGI )就是其中之一, CGI 提供一组方法在响应浏览器请求时运行一些扩展程序。 CGI 之所以被称为通用,是因为它能在大多数程序或脚本中被调用,包括: Perl , Python , awk , Unix shell scripting 等,甚至包括 Java 。当然,你大概不会把一个 Java 应用程序当作 CGI 来运行,毕竟这样太过原始。一般而言,开发 Servlet 总要比 CGI 具有更好的效率,因为当用户点击一个链接或一个按钮时,你不需要从操作系统层开始进行处理。
Tomcat 包括一个可选的 CGI Servlet ,允许你运行遗留下来的 CGI 脚本。
为了使 Tomcat 能够运行 CGI ,你必须做如下几件事:
1. 把 servlets-cgi.renametojar (在 CATALINA_HOME/server/lib/ 目录下)改名为 servlets-cgi.jar 。处理 CGI 的 servlet 应该位于 Tomcat 的 CLASSPATH 下。
2. 在 Tomcat 的 CATALINA_BASE/conf/web.xml 文件中,把关于 <servlet-name> CGI 的那段的注释去掉(默认情况下,该段位于第 241 行)。
3. 同样,在 Tomcat 的 CATALINA_BASE/conf/web.xml 文件中,把关于对 CGI 进行映射的那段的注释去掉(默认情况下,该段位于第 299 行)。注意,这段内容指定了 HTML 链接到 CGI 脚本的访问方式。
4. 你可以把 CGI 脚本放置在 WEB-INF/cgi 目录下(注意, WEB-INF 是一个安全的地方,你可以把一些不想被用户看见或基于安全考虑不想暴露的文件放在此处),或者你也可以把 CGI 脚本放置在 context 下的其他目录下,并为 CGI Servlet 调整 cgiPathPrefix 初始化参数。这就指定的 CGI Servlet 的实际位置,且不能与上一步指定的 URL 重名。
5. 重新启动 Tomcat ,你的 CGI 就可以运行了。
在 Tomcat 中, CGI 程序缺省放置在 WEB-INF/cgi 目录下,正如前面所提示的那样, WEB-INF 目录受保护的,通过客户端的浏览器无法窥探到其中内容,所以对于放置含有密码或其他敏感信息的 CGI 脚本而言,这是一个非常好的地方。为了兼容其他服务器,尽管你也可以把 CGI 脚本保存在传统的 /cgi-bin 目录,但要知道,在这些目录中的文件有可能被网上好奇的冲浪者看到。另外,在 Unix 中,请确定运行 Tomcat 的用户有执行 CGI 脚本的权限。
9 .改变 Tomcat 中的 JSP 编译器( JSP Compiler )
在 Tomcat 4.1 (或更高版本,大概), JSP 的编译由包含在 Tomcat 里面的 Ant 程序控制器直接执行。这听起来有一点点奇怪,但这正是 Ant 有意为之的一部分,有一个 API 文档指导开发者在没有启动一个新的 JVM 的情况下,使用 Ant 。这是使用 Ant 进行 Java 开发的一大优势。另外,这也意味着你现在能够在 Ant 中使用任何 javac 支持的编译方式,这里有一个关于 Apache Ant 使用手册的 javac page 列表。使用起来是容易的,因为你只需要在 <init-param> 元素中定义一个名字叫 “compiler” ,并且在 value 中有一个支持编译的编译器名字,示例如下:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>
org.apache.jasper.servlet.JspServlet
</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>WARNING</param-value>
</init-param>
<init-param>
<param-name>compiler</param-name>
<param-value>jikes</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
当然,给出的编译器必须已经安装在你的系统中,并且 CLASSPATH 可能需要设置,那处决于你选择的是何种编译器。
10 .限制特定主机访问( Restricting Access to Specific Hosts )
有时,你可能想限制对 Tomcat web 应用的访问,比如,你希望只有你指定的主机或 IP 地址可以访问你的应用。这样一来,就只有那些指定的的客户端可以访问服务的内容了。为了实现这种效果, Tomcat 提供了两个参数供你配置: RemoteHostValve 和 RemoteAddrValve 。
通过配置这两个参数,可以让你过滤来自请求的主机或 IP 地址,并允许或拒绝哪些主机 /IP 。与之类似的,在 Apache 的 httpd 文件里有对每个目录的允许 / 拒绝指定。
例如你可以把 Admin Web application 设置成只允许本地访问,设置如下:
<Context path="/path/to/secret_files" ...>
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.0.0.1" deny=""/>
</Context>
如果没有给出允许主机的指定,那么与拒绝主机匹配的主机就会被拒绝,除此之外的都是允许的。与之类似,如果没有给出拒绝主机的指定,那么与允许主机匹配的主机就会被允许,除此之外的都是拒绝的。