配置系统管理(Admin Web Application)
大多数商业化的JEE服务器都提供一个功能强大的管理界面且大都采用易于理解的Web应用界面Tomcat按照自己的方式同样提供一个成熟的管理工具并且丝毫不逊于那些商业化的竞争对手Tomcat的Admin Web Application最初在版本时出现当时的功能包括管理contextdata sourceuser和group等当然也可以管理像初始化参数usergrouprole的多种数据库管理等在后续的版本中这些功能将得到很大的扩展但现有的功能已经非常实用了Admin Web Application被定义在自动部署文件
CATALINA_BASE/webapps/adminxml (译者注CATALINA_BASE即tomcat安装目录下的server目录)你必须编辑这个文件以确定Context中的docBase参数是绝对路径也就是说CATALINA _BASE/webapps/adminxml的路径是绝对路径作为另外一种选择你也可以删除这个自动部署文件而在serverxml文件中建立一个Admin Web Application的context效果是一样的你不能管理Admin Web Application这个应用换而言之除了删除CATALINA_BASE/webapps/adminxml 你可能什么都做不了
如果你使用UserDatabaseRealm(默认)你将需要添加一个user以及一个role到CATALINA_BASE/conf/tomcatusersxml文件中你编辑这个文件添加一个名叫admin的role 到该文件中如下
<role name=admin/>
你同样需要有一个用户并且这个用户的角色是admin象存在的用户那样添加一个用户(改变密码使其更加安全)
<user name=admin
password=deep_dark_secret
roles=admin/>
当你完成这些步骤后请重新启动Tomcat访//localhost:/admin你将看到一个登录界面Admin Web Application采用基于容器管理的安全机制并采用了Jakarta Struts框架一旦你作为admin角色的用户登录管理界面你将能够使用这个管理界面配置Tomcat
配置应用管理(Manager Web Application)
Manager Web Application让你通过一个比Admin Web Application更为简单的用户界面执行一些简单的Web应用任务Manager Web Application被被定义在一个自动部署文件中CATALINA_BASE/webapps/managerxml
你必须编辑这个文件以确保context的docBase参数是绝对路径也就是说CATALINA_HOME/server/webapps/manager的绝对路径(译者注CATALINA_HOME即tomcat安装目录)如果你使用的是UserDatabaseRealm那么你需要添加一个角色和一个用户到CATALINA_BASE/conf/tomcatusersxml文件中接下来编辑这个文件添加一个名为manager的角色到该文件中
<role name=manager>
你同样需要有一个角色为manager的用户像已经存在的用户那样添加一个新用户(改变密码使其更加安全)
<user name=manager
password=deep_dark_secret
roles=manager/>
然后重新启动Tomcat访//localhost/manager/list将看到一个很朴素的文本型管理界面或者访//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应用停止一个应用使其无法被访问当有用户尝试访问这个被停止的应用时将看到一个的错误?? This application is not currently available
移除一个web应用只是指从Tomcat的运行拷贝中删除了该应用如果你重新启动Tomcat被删除的应用将再次出现(也就是说移除并不是指从硬盘上删除)部署一个web应用有两个办法可以在系统中部署web服务
拷贝你的WAR文件或者你的web应用文件夹(包括该web的所有内容)到$CATALINA_BASE/webapps目录下
为你的web服务建立一个只包括context内容的XML片断文件并把该文件放到$CATALINA_BASE/webapps目录下这个web应用本身可以存储在硬盘上的任何地方
如果你有一个WAR文件你若想部署它则只需要把该文件简单的拷贝到CATALINA_BASE/webapps目录下即可文件必须以war作为扩展名一旦Tomcat监听到这个文件它将(缺省的)解开该文件包作为一个子目录并以WAR文件的文件名作为子目录的名字
接下来Tomcat将在内存中建立一个context就好象你在serverxml文件里建立一样当然其他必需的内容将从serverxml中的DefaultContext获得
部署web应用的另一种方式是写一个Context XML片断文件然后把该文件拷贝到CATALINA_BASE/webapps目录下一个Context片断并非一个完整的XML文件而只是一个context元素以及对该应用的相应描述
这种片断文件就像是从serverxml中切取出来的context元素一样所以这种片断被命名为context片断
举个例子如果我们想部署一个名叫MyWebAppwar的应用该应用使用realm作为访问控制方式我们可以使用下面这个片断
<!
Context fragment for deploying MyWebAppwar
>
<Context path=/demo
docBase=webapps/MyWebAppwar
debug= privileged=true>
<Realm className=
orgapachecatalinarealmUserDatabaseRealm
resourceName=UserDatabase/>
</Context>
把该片断命名为MyWebAppxml然后拷贝到CATALINA_BASE/webapps目录下
这种context片断提供了一种便利的方法来部署web应用你不需要编辑serverxml除非你想改变缺省的部署特性安装一个新的web应用时不需要重启动Tomcat
配置虚拟主机(Virtual Hosts)
关于serverxml中Host这个元素只有在你设置虚拟主机的才需要修改虚拟主机是一种在一个web服务器上服务多个域名的机制对每个域名而言都好象独享了整个主机实际上大多数的小型商务网站都是采用虚拟主机实现的这主要是因为虚拟主机能直接连接到Internet并提供相应的带宽以保障合理的访问响应速度另外虚拟主机还能提供一个稳定的固定IP
基于名字的虚拟主机可以被建立在任何web服务器上建立的方法就是通过在域名服务器(DNS)上建立IP地址的别名并且告诉web服务器把去往不同域名的请求分发到相应的网页目录因为这篇文章主要是讲Tomcat我们不准备介绍在各种操作系统上设置DNS的方法如果你在这方面需要帮助请参考《DNS and Bind》一书作者是Paul Albitz and Cricket Liu (OReilly)为了示范方便我将使用一个静态的主机文件因为这是测试别名最简单的方法
在Tomcat中使用虚拟主机你需要设置DNS或主机数据为了测试为本地IP设置一个IP别名就足够了接下来你需要在serverxml中添加几行内容如下
<Server port=
shutdown=SHUTDOWN debug=>
<Service name=TomcatStandalone>
<Connector className=
yotetomcatCoyoteConnector
port=
minProcessors= maxProcessors=
enableLookups=true
redirectPort=/>
<Connector className=
yotetomcatCoyoteConnector
port= minProcessors=
maxProcessors=
acceptCount= debug=
scheme=https secure=true/>
<Factory className=yote
tomcatCoyoteServerSocketFactory
clientAuth=false protocol=TLS />
</Connector>
<Engine name=Standalone
defaultHost=localhost debug=>
<! This Host is the default Host >
<Host name=localhost
debug= appBase=webapps
unpackWARs=true autoDeploy=true>
<Context path= docBase=ROOT debug=/>
<Context path=/orders
docBase=/home/ian/orders debug=
reloadable=true crossContext=true>
</Context>
</Host>
<! This Host is the first
Virtual Host: >
<Host name=
appBase=/home/example/webapp>
<Context path= docBase=/>
</Host>
</Engine>
</Service>
</Server>
Tomcat的serverxml文件在初始状态下只包括一个虚拟主机但是它容易被扩充到支持多个虚拟主机在前面的例子中展示的是一个简单的serverxml版本其中粗体部分就是用于添加一个虚拟主机每一个Host元素必须包括一个或多个context元素所包含的context元素中必须有一个是默认的context这个默认的context的显示路径应该为空(例如path=)
配置基础验证(Basic Authentication)
容器管理验证方法控制着当用户访问受保护的web应用资源时如何进行用户的身份鑒别当一个web应用使用了Basic Authentication(BASIC参数在webxml文件中automethod元素中设置)而有用户访问受保护的web应用时Tomcat将通过HTTP Basic Authentication方式弹出一个对话框要求用户输入用户名和密码在这种验证方法中所有密码将被以位的编码方式在网络上传输
注意使用Basic Authentication通过被认为是不安全的因为它没有强健的加密方法除非在客户端和服务器端都使用HTTPS或者其他密码加密码方式(比如在一个虚拟私人网络中)若没有额外的加密方法网络管理员将能够截获(或滥用)用户的密码
但是如果你是刚开始使用Tomcat或者你想在你的web应用中测试一下基于容器的安全管理Basic Authentication还是非常易于设置和使用的只需要添加<securityconstraint>和<loginconfig>两个元素到你的web应用的webxml文件中并且在CATALINA_BASE/conf/tomcatusersxml文件中添加适当的<role>和<user>即可然后重新启动Tomcat
下面例子中的webxml摘自一个俱乐部会员网站系统该系统中只有member目录被保护起来并使用Basic Authentication进行身份验证请注意这种方式将有效的代替Apache web服务器中的htaccess文件<!
Define the
Membersonly area
by defining
a Security Constraint
on this Application and
mapping it to the
subdirectory (URL) that we want
to restrict
>
<securityconstraint>
<webresourcecollection>
<webresourcename>
Entire Application
</webresourcename>
<urlpattern>/members/*</urlpattern>
</webresourcecollection>
<authconstraint>
<rolename>member</rolename>
</authconstraint>
</securityconstraint>
<! Define the Login
Configuration for
this Application >
<loginconfig>
<authmethod>BASIC</authmethod>
<realmname>My Club
Membersonly Area</realmname>
</loginconfig>
配置单点登录(Single SignOn)
一旦你设置了realm和验证的方法你就需要进行实际的用户登录处理一般说来对用户而言登录系统是一件很麻烦的事情你必须尽量减少用户登录验证的次数作为缺省的情况当用户第一次请求受保护的资源时每一个web应用都会要求用户登录
如果你运行了多个web应用并且每个应用都需要进行单独的用户验证那这看起来就有点像你在与你的用户搏斗用户们不知道怎样才能把多个分离的应用整合成一个单独的系统所有他们也就不知道他们需要访问多少个不同的应用只是很迷惑为什么总要不停的登录
Tomcat 的single signon特性允许用户在访问同一虚拟主机下所有web应用时只需登录一次为了使用这个功能你只需要在Host上添加一个SingleSignOn Valve元素即可如下所示
<Valve className=
orgapachecatalina
authenticatorSingleSignOn
debug=/>
在Tomcat初始安装后serverxml的注释里面包括SingleSignOn Valve配置的例子你只需要去掉注释即可使用那么任何用户只要登录过一个应用则对于同一虚拟主机下的所有应用同样有效使用single signon valve有一些重要的限制
> value必须被配置和嵌套在相同的Host元素里并且所有需要进行单点验证的web应用(必须通过context元素定义)都位于该Host下
> 包括共享用户信息的realm必须被设置在同一级Host中或者嵌套之外
> 不能被context中的realm覆盖
> 使用单点登录的web应用最好使用一个Tomcat的内置的验证方式(被定义在webxml中的<authmethod>中)这比自定义的验证方式强Tomcat内置的的验证方式包括basicdigestform和clientcert
> 如果你使用单点登录还希望集成一个第三方的web应用到你的网站中来并且这个新的web应用使用它自己的验证方式而不使用容器管理安全那你基本上就没招了你的用户每次登录原来所有应用时需要登录一次并且在请求新的第三方应用时还得再登录一次
当然如果你拥有这个第三方web应用的源码而你又是一个程序员你可以修改它但那恐怕也不容易做
> 单点登录需要使用cookies
配置用户定制目录(Customized User Directores)
一些站点允许个别用户在服务器上发布网页例如一所大学的学院可能想给每一位学生一个公共区域或者是一个ISP希望给一些web空间给他的客户但这又不是虚拟主机在这种情况下一个典型的方法就是在用户名前面加一个特殊字符(~)作为每位用户的网站比如
~username
~username
Tomcat提供两种方法在主机上映射这些个人网站主要使用一对特殊的Listener元素Listener的className属性应该是orgapachecatalinastartupUserConfiguserClass属性应该是几个映射类之一
如果你的系统是Unix它将有一个标准的/etc/passwd文件该文件中的帐号能够被运行中的Tomcat很容易的读取该文件指定了用户的主目录使用PasswdUserDatabase 映射类
<Listener className=
orgapachecatalinastartupUserConfig
directoryName=public_html
userClass=orgapachecatalina
startupPasswdUserDatabase/>
web文件需要放置在像/home/users/ian/public_html或者/users/jbrittain/public_html一样的目录下面当然你也可以改变public_html 到其他任何子目录下
实际上这个用户目录根本不一定需要位于用户主目录下里面如果你没有一个密码文件但你又想把一个用户名映射到公共的像/home一样目录的子目录里面则可以使用HomesUserDatabase类
<Listener className=
orgapachecatalinastartupUserConfig
directoryName=public_html
homeBase=/home
userClass=orgapachecatalina
startupHomesUserDatabase/>
这样一来web文件就可以位于像/home/ian/public_html或者/home/jasonb/public_html一样的目录下这种形式对Windows而言更加有利你可以使用一个像c:\home这样的目录
这些Listener元素如果出现则必须在Host元素里面而不能在context元素里面因为它们都用应用于Host本身
在Tomcat中使用CGI脚本
Tomcat主要是作为Servlet/JSP容器但它也有许多传统web服务器的性能支持通用网关接口(Common Gateway Interface即CGI)就是其中之一CGI提供一组方法在响应浏览器请求时运行一些扩展程序
CGI之所以被称为通用是因为它能在大多数程序或脚本中被调用包括PerlPythonawkUnix shell scripting等甚至包括Java
当然你大概不会把一个Java应用程序当作CGI来运行毕竟这样太过原始一般而言开发Servlet总要比CGI具有更好的效率因为当用户点击一个链接或一个按钮时你不需要从操作系统层开始进行处理Tomcat包括一个可选的CGI Servlet允许你运行遗留下来的CGI脚本
为了使Tomcat能够运行CGI你必须做如下几件事
把servletscgirenametojar (在CATALINA_HOME/server/lib/目录下)改名为servletscgijar处理CGI的servlet应该位于Tomcat的CLASSPATH下
在Tomcat的CATALINA_BASE/conf/webxml 文件中把关于<servletname> CGI的那段的注释去掉(默认情况下该段位于第行)
同样在Tomcat的CATALINA_BASE/conf/webxml文件中把关于对CGI进行映射的那段的注释去掉(默认情况下该段位于第行)注意这段内容指定了HTML链接到CGI脚本的访问方式
你可以把CGI脚本放置在WEBINF/cgi 目录下(注意WEBINF是一个安全的地方你可以把一些不想被用户看见或基于安全考虑不想暴露的文件放在此处)或者你也可以把CGI脚本放置在context下的其他目录下并为CGI Servlet调整cgiPathPrefix初始化参数这就指定的CGI Servlet的实际位置且不能与上一步指定的URL重名
重新启动Tomcat你的CGI就可以运行了
在Tomcat中CGI程序缺省放置在WEBINF/cgi目录下正如前面所提示的那样WEBINF目录受保护的通过客户端的浏览器无法窥探到其中内容所以对于放置含有密码或其他敏感信息的CGI脚本而言这是一个非常好的地方
为了兼容其他服务器尽管你也可以把CGI脚本保存在传统的/cgibin目录但要知道在这些目录中的文件有可能被网上好奇的沖浪者看到另外在Unix中请确定运行Tomcat的用户有执行CGI脚本的权限 改变Tomcat中的JSP编译器(JSP Compiler)
在Tomcat (或更高版本大概)JSP的编译由包含在Tomcat里面的Ant程序控制器直接执行这听起来有一点点奇怪但这正是Ant有意为之的一部分有一个API文档指导开发者在没有启动一个新的JVM的情况下使用Ant
这是使用Ant进行Java开发的一大优势另外这也意味着你现在能够在Ant中使用任何javac支持的编译方式这里有一个关于Apache Ant使用手册的javac page列表
使用起来是容易的因为你只需要在<initparam> 元素中定义一个名字叫compiler并且在value中有一个支持编译的编译器名字示例如下
<servlet>
<servletname>jsp</servletname>
<servletclass>
orgapachejasperservletJspServlet
</servletclass>
<initparam>
<paramname>logVerbosityLevel
</paramname>
<paramvalue>WARNING</paramvalue>
</initparam>
<initparam>
<paramname>compiler</paramname>
<paramvalue>jikes</paramvalue>
</initparam>
<loadonstartup></loadonstartup>
</servlet>
当然给出的编译器必须已经安装在你的系统中并且CLASSPATH可能需要设置那处决于你选择的是何种编译器
限制特定主机访问(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=orgapache
catalinavalvesRemoteAddrValve
allow= deny=/>
</Context>
如果没有给出允许主机的指定那么与拒绝主机匹配的主机就会被拒绝除此之外的都是允许的与之类似如果没有给出拒绝主机的指定那么与允许主机匹配的主机就会被允许除此之外的都是拒绝的