Tomcat使用总结文档
目录
一、Tomcat介绍... - 4 -
1.1 tomcat简介... - 4 -
1.2 tomcat的结构... - 4 -
1.3 Tomcat 的获取... - 6 -
1.4 Tomcat的安装... - 6 -
1.5 测试tomcat的安装... - 7 -
二、Tomocat的目录结构... - 8 -
三、创建一个tomcat工程(web应用)... - 9 -
3.1 创建工程目录结构... - 9 -
3.2 创建web.xml文件以及配置... - 9 -
3.2.1 配置servlet过滤器... - 10 -
3.2.2 配置Servlet- 11 -
3.2.3 配置Session. - 12 -
3.2.4 配置Welcome文件清单... - 12 -
3.2.5 配置异常页面(<error-page>)... - 13 -
3.2.6 配置Tag Library. - 14 -
3.2.7 配置引用资源... - 14 -
3.2.8 配置安全约束... - 15 -
3.2.9 配置安全验证登录界面... - 16 -
3.2.10 配置对安全验证角色的引用... - 16 -
3.3 server.xml文件的配置... - 17 -
3.3.1 配置Server元素... - 18 -
3.3.2 配置Service元素... - 18 -
3.3.3 配置Engine元素... - 19 -
3.3.4 配置Host元素... - 19 -
3.3.5 配置Context元素... - 20 -
3.3.6 配置Connector元素... - 21 -
3.3.7 配置数据源<Resource>和<ResourceParams>. - 23 -
3.3.8 配置<Logger>元素... - 24 -
3.3.9 配置Tomcat阀(Valve)... - 25 -
3.3.9.1 配置客户访问日志阀(Access Log Valve)... - 26 -
3.3.9.2 配置远程地址过滤器(Remote Address Filter)... - 27 -
3.3.9.3 配置远程主机过滤器(Remote Host Filter)... - 27 -
3.3.9.4 配置客户请求记录器(Request Dumper)... - 28 -
四、在server.xml文件中配置<Realm>元素... - 29 -
4.1内存域(MemoryRealm)... - 29 -
4.1.1 MemoryRealm元素属性... - 29 -
4.1.2 User文件格式... - 30 -
4.1.3 MemoryRealm注意事项... - 30 -
4.2 JDBC域(JDBCRealm)... - 30 -
4.2.1配置JDBC域... - 31 -
4.2.2 JDBCRealm的属性说明... - 31 -
4.2.3 JDBCRealm使用遵循的规则... - 32 -
4.3 DataSourceRealm.. - 32 -
4.3.1 配置DataSourceRealm.. - 33 -
4.3.2 DataSourceRealm 属性说明... - 33 -
4.3.3 DataSourceRealm注意事项... - 34 -
4.4 JNDIRealm.. - 34 -
4.4.1 连接目录... - 35 -
4.4.2 选择用户目录入口... - 35 -
4.4.3对用户进行认证... - 35 -
4.4.4 为用户分配角色... - 36 -
4.4.5配置JNDIRealm.. - 36 -
4.4.6实例... - 37 -
4.4.7注意事项... - 40 -
五、创建并发布WAR文件... - 41 -
六、配置虚拟主机并发布WEB应用... - 41 -
Jakarta Tomcat服务器是在SUN公司的JSWDK(JavaServer Web DevelopmentKit,是SUN公司推出的小型Servlet/JSP调试工具)的基础上发展起来的一个优秀的Servlet/JSP容器,它是Apache-Jakarta软件组织的一个子项目。它不但支持运行Servlet和JSP,而且还具备了作为商业Java Web应用容器的特征。
作为一个开放源码的软件,Tomcat得到了开放源码志愿者的广泛支持,它可以和目前大部分的主流HTTP服务器(如IIS和Apache服务器)一起工作,而且运行稳定、可靠、效率高。
Tomcat服务器除了能够运行servlet和JSP,还提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等,Tomcat已成为目前开发企业Java Web应用的最佳选择之一。
Tomcat服务器是由一系列可配置的组件构成,其中核心的组件是Catalina Servlet容器,它是所有其他Tomcat组件的顶层容器。Tomcat的组件在<CATALINA_HOME>/conf/server.xml文件中进行配置,每个Tomcat组件在server.xml文件中对应一种配置元素。一下代码以XML的形式展示各种Tomcat组件之间的关系:
<Server>
<Service>
<Connector/>
<Engine>
<Host>
<Context>
</Context>
</Host>
</Engine>
</Service>
</Server>
以上XML代码中,每个元素都代表一种tomcat组件。这些元素可以分为4类。
1、顶层类元素
顶层类元素包括<Server>元素和<Service>元素,它们位于整个配置文件的顶层。
2、连接器类元素
连接器类元素<Connector>代表了介于客户和服务器之间的通信接口,负责将客户的请求发送给服务器,并将服务器的响应结果传递给客户。
3、容器类元素
容器类元素代表处理客户请求并生成相应响应结果的组件,有3种容器类元素,它们是Engine、Host、Context。Engine组件为特定的Service组件处理所有的客户请求,Host组件为特定的虚拟主机处理所有的客户请求,Context组件为特定的Web应用处理所有的客户请求。
4、嵌套类元素
嵌套类元素代表了可以加入到容器中的组件,如<Logger>元素、<Valve>元素和<Realm>元素。
下面简要介绍下以上元素,具体配置server.xml,将在下文具体给出介绍。
·<Server>元素
<Server>元素代表整个Catalina Servlet容器,它是Tomcat实例的顶层元素。<Server>元素可以包含一个或多个<Service>元素。
·<Service>元素
<Service>元素中包含一个<Engine>元素,以及一个或多个<Connector>元素,这些<Connector>元素共享一个<Engine>元素。
·<Connector>元素
<Connector>元素代表和客户程序实际的交互的组件,它负责接收客户的请求,以及向客户返回响应结果。
·<Engine>元素
每个<Service>元素只能包含一个<Engine>元素。<Engine>元素处理在同一个<Service>中所有<Connector>元素接收到的客户请求。
·<Host>元素
一个<Engine>元素中可以包含多个<Host>元素。每个<Host>元素定义一个虚拟主机,它可以包含一个或多个Web应用。
·<Context>元素
<Context>元素是使用最频繁的元素。每个<Context>元素代表了运行在虚拟主机上的单个web应用。一个<Host>元素可以包含多个<Context>元素。
Tomcat各个组件之间的嵌套关系如下图:
Tomcat的下载地址是http://tomcat.apache.org/download-55.cgi,进入页面下载apache-tomcat-5.5.27.zip或者apache-tomcat-5.5.27.exe文件。
同时还用在http://java.sun.com/j2se/1.6/下载j2sdk-1.6。
对于Windows操作系统,Tomcat5提供了两种安装文件,一个文件为apache-tomcat-5.5.27.zip,还有一个文件是apache-tomcat-5.5.27.exe。apache-tomcat-5.5.27.exe是可执行的安装程序,通过这个程序安装Tomcat,会自动把Tomcat服务加入到Windows操作系统的服务中,并且在【开始】->【程序】菜单中加入了Tomcat服务器的管理菜单。
本节介绍apache-tomcat-5.5.27.zip的安装。
在安装tomcat之前,首先安装JDK。
接下来,解压Tomcat压缩文件apache-tomcat-5.5.27.zip,解压到压缩文件过程就相当于安装的过程。假定解压至C:\jakarta-tomcat目录。
然后,设定环境变量:JAVA_HOME,它是JDK的安装目录;CATALINA_HOME,它是Tomcat的安装目录。
在Windows 操作环境下设置环境步骤如下:
(1) 打开“控制面板”,选择“系统”图标。
(2) 双击“系统”图标,运行Windows NT/2000系统程序,选择【高级】标签。
(3) 在对话框中单击【环境变量】按钮。
(4) 单击“系统变量”区域的【新建】按钮,将会弹出“新建环境变量”对话框,在对话框中新建JAVA_HOME环境变量,环境变量为JDK的安装目录。
(5) 重复步骤4,新建CATALINA_HOME环境变量,其环境变量为apache-tomcat-5.5.27.zip的解压后的目录。
在tomcat的解压文件中,运行\bin\startup.bat文件启动tomcat。然后在打开IE,在地址栏中输入http://localhost:8080/回车,如果能正常打开tomcat的欢迎页面,就说tomcat安装成功。
Tomcat服务器采用的是HTTP端口为“8080”,如果想采用其他的端口,如“80”,可以修改<CATALINA_HOME>/conf/server.xml,将<Connector>元素的port值改为“80”,然后重启tomcat。
Tomcat的目录结构即apache-tomcat-5.5.27.zip的解压后的子目录,也是apache-tomcat-5.5.27.exe安装后的子目录。
其主要包括以下目录:
目录 |
描述 |
/bin |
主要存放Windows平台以及Linux平台上启动和关闭tomcat的脚本文件。 |
/conf |
存放Tomcat服务器的各种配置文件,其中最重要的配置文件是server.xml。 |
/server |
包含3个子目录:class,lib和webapps。 |
/server/lib |
存放tomcat服务器所需的各种JAR文件。 |
/server/wabapps |
存放tomcat自带的两个Web应用:admin应用和manager应用。 |
/common/lib |
存放tomcat 服务器以及所有Web应用都可以访问的JAR文件。 |
/shared/lib |
存放所有Web应用都可以访问的JAR文件。 |
/logs |
存放tomcat的日志文件。 |
/webapps |
当发布Web应用时,默认情况下把Web应用文件放于此文件下。 |
/works |
Tomcat吧由JSP生成的Servlet放于此目录下。 |
在/server/lib目录、/common/lib目录、/shared/lib目录下都可以放JAR文件,它们的区别在于:
/server/lib目录下的JAR文件只可以被tomcat服务器访问。
/shared/lib目录下的JAR文件可以被所有的web应用访问,但不可以被tomcat服务器访问。
/common/lib目录下的JAR文件可以被tomcat服务器和所有的web应用访问。
Tomcat工程具有固定的目录结构,这里假定开发一个名为helloapp的tomcat工程,首先应该在<CATALINA_HOME>/webapps目录下创建这个tomcat工程的目录结构。需创建的目录结构如下:
目录 |
描述 |
/helloapp |
Web应用的根目录,所有的JSP和HTML文件都放在此目录下 |
/helloapp/WEB-INF |
存放web应用的发布描述文件web.xml |
/helloapp/WEB-INF/class |
存放各种class文件,Servlet类文件也放于此目录下 |
/helloapp/WEB-INF/lib |
存放web应用所需的各种JAR文件 |
web.xml是web应用发布描述文件,是在Sevlet规范中定义的。它是Web应用的配置文件。web.xml中的元素和Tomcat容器完全独立。
web.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
</web-app>
web.xml文件依次定义了如下元素:
● <web-app> web.xml中的顶层元素,其他的所有的子元素都要定义在<web-app>内。
● <display-name> 定义web应用的名字
● <description> 声明web应用的描述信息。
● <filter>
● <filter-mapping>
● <servlet>
● <servlet-mapping>
● <session-config>
● <welcome-file-list>
● <taglib>
● <resource-ref>
● <security-constraint>
● <login-config>
● <security-role>
注意:在web.xml中元素定义的先后顺序不能颠倒,否则tomcat服务器可能会抛出SAXParseException。
web.xml文件中的开头几行是固定的,它定义了该文件的字符编码、XML的版本以及引用的DTD文件。
一下介绍几种常用的元素配置:
对于Servlet容器收到的客户请求,以及发出的响应的结果,Servlet都能检查还修改其中的信息。
所有的servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有三个过滤器类必须事先的方法:
● init(FilterConfig):这是Servlet过滤器的初始方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml文件中Servlet过滤器的初始化参数。
● doFilter(ServletRequest,ServletResponse,FilterChain):这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器。
● destroy():Servlet容器在销毁过滤器实例钱调用该方法,在这个方法中可以释放Servlet过滤器占用的资源。
在web应用中加入Servlet过滤器,需要在万恶不。Web.xml中配置两个元素<filter>和<filter-mapping>。一下是<filter>元素的示范代码:
<filter>
<filter-name>SampleFilter</filter-name>
<filter-class>mypack.SampleFilter</filter-class>
</filter>
<filter>元素的属性:
● <filter-name> :定义过滤器的名字,当web应用中有多个过滤器时,不允许过滤器重名。
● <filter-class>:指定实现这一过滤器的类,这个类负责具体的过滤事务。
<filter-mapping>
<filter-name>SampleFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>元素的属性
●<filter-name>:指定过滤器名字,这里的过滤器名必须和<filter>元素中定义的过滤器名字匹配。
●<url-pattern>:指定过滤器负责过滤的URL。
Servlet的框架核心是javax.servlet.Servlet接口,所有的Servlet都必须事先这一接口,在Servlet接口中定义了5个方法,其中的3个方法代表了servlet的生命周期:
● init方法,负责初始化Servlet对象。
● service方法,负责相应客户请求。
● destroy方法,当Servlet对象退出生命周期时,负责释放占用的资源。
如果要实现一个sevlet类可以有以下几种放方法实现:
2. 实现servlet接口,实现init方法、service方法和destroy方法。
3. 扩展GenericServlet类
如果servlet类扩展了GenericServlet类,则必须要实现service方法,因为GenericServlet类中的service方法被声明为抽象方法,改方法声明如下:
public abstract void service(ServletRequest request,ServletResponse)
throws ServletException,IOException;
service方法有两个参数:ServletRequest和ServletResponse。Servlet容器将客户的请求信息封装在ServletRequest中,传给service方法;service方法将响应客户的结果通过ServletResponse对象传递给客户。
4. 扩展HttpServlet类
如果Servlet类扩展了HttpServlet类,需要覆写父类中的doGet和doPost方法。
在web.xml中配置servlet:
<servlet> 用来声明一个servlet的数据,主要有以下子元素:
<servlet-name></servlet-name> 指定servlet的名称
<servlet-class></servlet-class> 指定servlet的类名称
<jsp-file></jsp-file> 指定web站台中的某个JSP网页的完整路径
<init-param> 用来定义参数
<param-name></param-name> 指定参数名称
<param-value></param-value> 指定参数数值
</init-param>
<load-on-startup></ load-on-startup >
</servlet>
<servlet>元素属性
属性 |
描述 |
<servlet-name> |
定义servlet的名字 |
<servlet-class> |
指定实现这个servlet的类 |
<init-param> |
定义servlet的初始化参数(包括参数和参数值),一个<servlet>元素中可以有多个<init-param>,在Servlet类中通过getInitParameter(String name)方法访问初始化参数。 |
<load-on-startup> |
指定当web应用程序启动时,装载Servlet的次序,当这个值为正数或者零时,Servlet容器先加载数值小的Servlet,再依次加载其他数值大的Servlet,如果这个值为负数或者没有设定时,那么servlet容器在web客户首次访问这个servlet时加载它。 |
同样,与<servlet></servlet>一起使用的是<servlet-mapping></servlet-mapping> 用来定义servlet所对应的URL,包含两个子元素:
<servlet-mapping>
<servlet-name></servlet-name> 指定servlet的名称
<url-pattern></url-pattern> 指定servlet所对应的URL
</servlet-mapping>
<session-config>元素是用来设定HttpSession的生命周期。一旦指定session的生命周期,session可以保持不活动的状态最长不能超过这一时间,一旦超过这个时间,Servlet容器将把它作为无效Session处理。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<session-config>元素只包括这一个属性<session-timeout>,它用来设定Session可以保持的不活动的最长时间,这里采用的时间单位为“秒”。
当客户访问web应用时,如果仅仅给出web应用的Root URL,没有指定具体的文件名,Servlet容器会自动调用Web应用的Welcome文件。
<welcome-file-list>元素用来设定welcome文件清单。以下代码中声明了两个Welcome文件:login.jsp和index.htm.
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<welcome-file-list>元素中可以包含多个<welcome-file>,当Servlet容器调用Web应用的Welcome文件时,首先寻找第一个<welcome-file>指定的文件,如果不存在,依次寻找下一Welcome文件,知道找到为止。
配置异常或者代码错误页面格式如下:
<error-page> 用来处理错误代码或异常的页面,有三个子元素:
<error-code></error-code> 指定错误代码
<exception-type></exception-type> 指定一个JAVA异常类型
<location></location> 指定在web站台内的相关资源路径
</error-page>
例如:
<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/exception.jsp</location>
</error-page>
<taglib>元素用来设置Web应用所应用的Tag Library。有两个子元素:
△ <taglib-uri></taglib-uri> 定义TLD文件的URI,在JSP网页中用taglib指令便可取得该URI的TLD文件。
△ <taglib-location></taglib-location> 指定TLD文件相对于web站台的存放位置。
例如
<taglib>
<taglib-uri>myTaglib</taglib-uri>
<taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
</taglib>
此时JSP页面可通过下面的形式使用标签库
<%@ taglib uri="/struts-html" prefix="html" %>
<html:text name="name" value="tomcat" />
如果Web应用访问了由Servlet容器管理的某个JNDI Resource,必须在web.xml文件中声明对JNDI Resource的引用。表示资源引用的元素为<resource-ref>,以下是声明引用jdbc/SampleDB数据源的例子:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/sampleDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>的属性描述:
属性 |
描述 |
<description> |
对所引用的资源说明 |
<res-ref-name> |
指定引用资源的JNDI名字 |
<res-type> |
指定所引用的资源的名字 |
<res-auth> |
指定管理所引用资源的Manager,它有两个可选值:Container和Application。Container表示容器来创建和管理Resource,Application表示由web应用来创建和管理Resource。 |
<security-constraint>用来为Web应用定义安全约束。以下代码指明当用户访问该Web应用下所有的的资源,必须具备guest角色。
<security-constraint>
<web-resource-collection>
<web-resource-name>sample application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>guest</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>元素的属性
属性 |
描述 |
<web-resource-collection> |
声明受保护的Web资源 |
<auth-constraint> |
声明可以访问受保护资源的角色,可以包含多个<role-name>子元素。 |
<web-resource-collection>元素的属性
属性 |
描述 |
<web-resource-name> |
标识受保护的Web资源 |
<url-pattern> |
指定受保护的URL路径 |
<login-config>元素指定当Web客户访问受保护的Web资源时,系统弹出的登录对话框的类型。以下代码配置了基于表单验证的登录界面:
<login-config>
<auth-method>FROM</auth-method>
<realm-name>Tomcat Server Configuration From Based Authentication
</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</from-login-config>
</login-config>
<login-config>元素的各个属性说明如下:
属性 |
描述 |
<auth-method> |
指定验证方法,它有3个可选值:BASIC(基本验证)、DIGEST(摘要验证)、FORM(基于表单的验证). |
<realm-name> |
设定安全域的名称 |
<form-login-config> |
当验证方法为FORM时,配置验证网页和出错的网页 |
<form-login-page> |
当验证方法为FORM时,设定验证网页 |
<form-error-page> |
当验证方法为FORM时,设定出错网页 |
<security-role>元素指明这个Web应用引用的所有角色名字。例如,以下代码声明引用guest角色。
<security-role>
<description>
The role that is required to log in to the sample Application
</description>
<role-name>guest</role-name>
</security-role>
Tomcat服务器是由一系列可配置的组件构成,Tomcat的组件可以在
<CATALINA_HOME>\conf\server.xml文件中进行配置,每个Tomcat组件和server.xml文件中的一种配置相对应。以下代码以XML的形式展示各种Tomcat组件之间的关系:
<Server>
<Service>
<Connector>
<Engine>
<Host>
<Context>
</Context>
</Host>
</Engine>
</Connector>
</Service>
</Server>
以上XML代码中,每个元素都代表一种tomcat组件。这些元素可以分为4类。
5、顶层类元素
顶层类元素包括<Server>元素和<Service>元素,它们位于整个配置文件的顶层。
6、连接器类元素
连接器类元素<Connector>代表了介于客户和服务器之间的通信接口,负责将客户的请求发送给服务器,并将服务器的响应结果传递给客户。
7、容器类元素
容器类元素代表处理客户请求并生成相应响应结果的组件,有3种容器类元素,它们是Engine、Host、Context。Engine组件为特定的Service组件处理所有的客户请求,Host组件为特定的虚拟主机处理所有的客户请求,Context组件为特定的Web应用处理所有的客户请求。
8、嵌套类元素
嵌套类元素代表了可以加入到容器中的组件,如<Logger>元素、<Valve>元素和<Realm>元素。
下面简要介绍下以上元素,具体配置server.xml,将在下文具体给出介绍。
◆<Server>元素
<Server>元素代表整个Catalina Servlet容器,它是Tomcat实例的顶层元素。<Server>元素可以包含一个或多个<Service>元素。
◆<Service>元素
<Service>元素中包含一个<Engine>元素,以及一个或多个<Connector>元素,这些<Connector>元素共享一个<Engine>元素。
◆<Connector>元素
<Connector>元素代表和客户程序实际的交互的组件,它负责接收客户的请求,以及向客户返回响应结果。
◆<Engine>元素
每个<Service>元素只能包含一个<Engine>元素。<Engine>元素处理在同一个<Service>中所有<Connector>元素接收到的客户请求。
◆<Host>元素
一个<Engine>元素中可以包含多个<Host>元素。每个<Host>元素定义一个虚拟主机,它可以包含一个或多个Web应用。
◆<Context>元素
<Context>元素是使用最频繁的元素。每个<Context>元素代表了运行在虚拟主机上的单个web应用。一个<Host>元素可以包含多个<Context>元素。
<Server>元素代表整个Catalina Servlet容器,它是Tomcat实例的顶层元素,由org.apache.catalina.Server接口来定义。<Server>元素可包含一个或多个<Service>元素,但<Server>元素不能作为任何其他元素的子元素。在server.xml文件中定义了如下的<Server>元素:
<Server port=”8005” shutdown=”SHUTDOWN” debug=”0”>
<Server>元素的属性描述如下表:
描述 |
属性 |
className |
指定实现org.apache.catalina.Server接口的类,默认值是 org.apache.catalina.StandardServer |
port |
指定Tomcat服务器监听shutdown命令的端口。终止Tomcat服务器运行时,必须在Tomcat服务器所在的机器上发出shutdown命令。该属性是必须设定的。 |
shutdown |
指定终止Tomcat服务器运行时,发给Tomcat服务器的shutdown监听端口的字符串,该属性是必须设定的。 |
<Service>元素是有org.apache.catalina.Service接口定义,它包含一个<Engine>元素,以及一个或多个<Connector>元素,这些元素共享同一个<Engine>元素。在server.xml文件中可以配置多个<Service>元素:
<Service name=”Catalina”>
<Service name=”Apache”>
第一个<Service>处理所有直接有Tomcat服务器接收到的Web客户请求,第二个<Service>处理由Apache服务器转发过来的Web客户请求。
<Service>元素的属性描述如下表:
描述 |
属性 |
className |
指定实现org.apache.catalina.Service的类,默认值为 org.apache.catalina.StandardServer |
name |
定义Service的名字 |
<Engine>元素由org.apache.catalina.Engine接口定义。每个<Service>元素只能包含一个<Engine>元素。<Engine>元素处理在同一个<Service>中所有的<Connector>元素接收到的客户请求,例如,在server.xml文件中配置以下<Engine>元素:
<Engine name=”Catalina” defaultHost=”localHost” debug=”0”>
<Engine>元素的属性描述如下:
描述 |
属性 |
className |
指定实现org.apache.catalina.Engine接口的类,默认值为org.apache.catalina.core.StandardEngine |
defaultHost |
指定处理客户请求的默认主机名,在<Engine>的<Host>子元素定义想、这一主机。 |
name |
定义Engine的名字 |
在<Engine>元素中可以包含以下子元素:
● <Logger>
● <Realm>
● <Valve>
● <Host>
<Host>元素由org.apache.catalina.Host接口定义。一个<Engine>元素可以包含多个<Host>元素,每个<Host>元素定义了一个虚拟主机,它可以包含一个或多个Web应用。
例如,在server.xml文件中配置了以下<Host>元素:
<Host name=”localhost” debug=”0” appBase=”webapps”
unpackWARs=”true” autoDeploy=”true”></Host>
以上代码定义了一个名为localhost的虚拟主机,Web客户访问它的URL为:
http://localhost:8080/
<Host>元素的属性描述如下:
描述 |
属性 |
className |
指定实现org.apache.catalina.Host借口的类,默认值为org.apache.catalina.core.StandardHost |
appBase |
指定虚拟主机的目录,可以指定绝对目录,也可以指定相对于<CATALINA_HOME>的相对目录,如果此项没有设定,默认值为<CATALINA_HOME>/webapps |
unpackWARs |
如果此项设为true,表示将吧Web应用的WAR文件先展开为开放目录结构后再运行。如果设为false,将直接运行WAR文件。 |
autoDeploy |
如果此项设为true,表示当Tomcat服务器处于运行状态时,能够监测appBase下的文件,如果有新的Web加入进来的话,会自动发布这个Web应用。 |
alias |
指定虚拟主机的别名,可以指定多个别名。 |
deployOnStartUp |
如果此项设置为true,表示Tomcat服务器启动时会自动发布webBase目录下的所有Web应用,如果Web应用在server.xml中没有相应的<Context>元素,将采用Tomcat默认的Context,deployOnStartUp的默认值为true。 |
name |
定义虚拟主机的名字 |
在<Host>元素中可以包含如下子元素:
● <Logger>
● <Realm>
● <Valve>
● <Context>
<Context>元素是由org.apache.catalina.Context接口定义。<Context>元素是使用最频繁的元素。每个<Context>元素代表了运行在虚拟主机上的单个Web应用。一个<Host>元素可以有多个<Context>元素。
例如,在server.xml文件中配置了一下<Context>元素:
<Context path=”/sample” dosBase=”sample” debug=”0”
Reladable=”true”>
……
</Context>
<Context>元素的属性描述参见下表:
描述 |
属性 |
className |
指定实现org.apache.catalina.Context接口的类,默认值是org.apache.catalina.core.StandardContext |
path |
指定访问该Web应用的URL入口 |
docBase |
指定Web应用的文件路径。可以给定绝对路径,也可以给定相对于Host的appBase属性的相对路径。如果Web应用采用开放目录结构,那就指定Web应用的根目录;如果Web应用是个WAR文件,那就指定WAR文件的路径 |
reloadable |
如果这个属性设置为true,Tomcat服务器在运行状态下会监视在WEB-INF/class和WEB-INF/lib目录下CLASS文件的改动。如果监测到有class被更新,服务器会自动加载Web应用。 |
cookies |
指定是否通过Cookies来支持Session,默认值为true。 |
useNaming |
指定是否支持JNDI,默认值是true。 |
在<Context>元素中可以包含以下子元素:
● <Logger>
● <Realm>
● <Valve>
● <Resource>
● <ResourceParams>
<Connector>元素由org.apache.catalina.Connector接口定义。<Connector>元素代表与客户程序交互的组件,它负责接收客户请求,以及向客户返回相应结果。
例如在下例的server.xml文件中定义了两个<Connector>元素:
<Connector port=”8080”
maxThreads=”150” minSpareTheads=”25” maxSpareTheads=”75”
enableLookups=”false”redirectPort=”8443” acceptCount=”100”
debug=”0” connectionTimeout=”20000”
disableUploadTimeout=”true”/>
<Connector port=”8009”
enableLookups=”false” redirectPort=”8443” debug=”0”
protocol=”AJP/1.3” />
第一个<Connector>元素定义了一个HTTP Connector,它通过8080端口接收HTTP请求,第二个<Connector>元素定义了一个JK Connector,它通过8009端口接收由其他HTTP服务器(如Apache服务器)转发过来的客户请求。
所有的<Connector>元素都具有一些共同的属性,这些属性如下表:
描述 |
属性 |
className |
指定实现org.apache.catalina.Connector接口的类。 |
enableLookups |
如果设置为true,表示支持域名解析,可以把IP地址解析为主机名。Web应用中调用request.getRemostHost方法则返回客户端主机名。该属性默认值为true。 |
redirectPort |
指定转发端口。如果当前端口只支持non-SSL请求,在需要安全通信的场合,将把客户请求转发给基于SSL的redirectPort端口。 |
HttpConnector的属性描述参见下表:
描述 |
属性 |
className |
指定实现org.apache.catalina.Connector接口的类,默认值为org.apache.catalina.Connector |
enableLookups |
如果设置为true,表示支持域名解析,可以把IP地址解析为主机名。Web应用中调用request.getRemostHost方法则返回客户端主机名。该属性默认值为true。 |
redirectPort |
指定转发端口。如果当前端口只支持non-SSL请求,在需要安全通信的场合,将把客户请求转发给基于SSL的redirectPort端口。 |
port |
设定TCP/IP端口号,默认为8080。 |
address |
如果服务器有两个以上的IP地址,该属性可以设定端口监听的IP地址,默认情况下,端口会监听服务器上所有的IP地址。 |
bufferSize |
设定由端口创建的输入流的缓存大小,默认值为2048byte。 |
protocol |
设定HTTP协议,默认值为HTTP/1.1。 |
maxThreads |
设定处理客户请求的线程的最大数目,这个值也决定了服务器可以同时相应客户请求的最大人数目,默认值为20。 |
acceptCount |
设定在监听端口队列中的最大客户请求数,默认值为10,如果队列已满,客户请求将被拒绝。 |
connectionTimeout |
定义建立客户连接超时的时间,以毫秒为单位。如果设置为-1,表示不限制建立客户连接的时间。 |
JK Connector的属性描述如下表:
描述 |
属性 |
className |
指定实现org.apache.catalina.Connector接口的类,默认值为org.apache.coyote.tomcat5.CoyoteConnector |
enableLookups |
如果设置为true,表示支持域名解析,可以把IP地址解析为主机名。Web应用中调用request.getRemostHost方法则返回客户端主机名。该属性默认值为true。 |
redirectPort |
指定转发端口。如果当前端口只支持non-SSL请求,在需要安全通信的场合,将把客户请求转发给基于SSL的redirectPort端口。 |
port |
设定AJP端口号。 |
protocl |
必须设定为AJP/1.3协议。 |
<Recource>元素用来定义JNDI Resource。在Tomcat中,DataSource是JNDI Resource的一种。<Recource>元素定义在<Context>元素中,如下例定义了一个名为jdbc/BookDB的数据源。
<!—name属性:指定Resource的JNDI名字;
auth属性:指定管理Resource的Manager,它有两个可选值:Containet和Application。Containet表示由容器来创建和管理Resource;Application表示由Web应用来创建和管理 Resource。
Type属性:指定Resource所属的Java类名。-->
<Resource name =”jdbc/BookDB”
auth=”Container”
type=”javax.sql.DataSource”/>
<ResourceParams name=”jdbc/BookDB”>
<!—指定生成DataResource的factory类名 -->
<parameter>
<name>factory</name>
<value>ort.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>
<parameter>
<name>driver</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/BookDB?autoReconnect=true
</value>
</parameter>
</ResourceParams>
在<ResourceParams>元素中指定了配置BookDB数据源的参数,<ResourceParams>元素的参数说明如下:
参数 |
描述 |
factory |
指定生成DataSesource的factory的类名。 |
maxActive |
指定数据库连接池中处于活动状态的数据库连接的最大数目,取值为0,表示不受限制。 |
maxIdle |
指定数据库连接池中处于空闲状态的数据库连接的最大数目,取值为0,表示不受限制。 |
maxWait |
指定数据库连接池中的数据库连接处于空闲状态的最长时间(以毫秒为单位),超过这一时间,将会抛出异常。取值为-1,表示不受限制。 |
username |
指定连接数据库的用户名。 |
password |
指定连接数据库的口令。 |
driverClassName |
指定连接数据库的JDBC驱动程序。 |
url |
指定连接数据库的URL。 |
<Logger>元素代表了Catalina容器的日志记录器,它可以嵌套在Engine、Host和Context这3中元素中。子类容器如果没有定义自己的<Logger>元素,将继承父类容器的<Logger>元素。
所有的<Logger>元素都包含以下属性:
▲ className:代表是实现日志记录器的类的名字。
▲ verbosity:指定日志记录器的日志级别。可选值包括:0(FATAL)、
1(ERROR)、2(WARNING)、3(INFO)和4(DEBUG)。只有级别比verbosity的值小或者相等的日志信息才会被输出到日志设备上。例如,如果verbosity的值为2(WARNING),那么FATAL、REEOR、WARNING类型的日志就会被输出到日志设备上,其他级别的日志被忽略。
一共有3中类型的Logger:FileLogger、SystemErrLogger和SystemOutLogger。
▲ FileLogger的实现类是org.apache.catalina.logger.FileLogger,它把日志信息保存到文件中,FileLogger的属性参见下表:
属性 |
描述 |
directory |
指定日志文件的绝对目录或相对于<CATALINA_HOME>的相对地址。该属性默认值为<CATALINA_HOME>/logs |
prefix |
指定日志文件名的前缀。 |
suffix |
指定日志文件名的扩展名。 |
timestamp |
如果设为true,表示将把生成的日志的时间也保持到日志文件中。 |
如下例,是为localhost配置FileLogger的代码:
<Host name=”localhost” debug=”0” appBase=”webapps”
unpackWARs=”true” autoDeploy=”true”>
<Logger className=” org.apache.catalina.logger.FileLogger”
Prefix=”localhost_log.” Suffix=”.txt”
Timestamp=”true”/>
▲ SystemErrLogger的实现类是
org.apache.cataline.logger. SystemErrLogger,它把日志信息输出到Tomcat服务器指定的标准错误输出流中,在默认的Tomcat的启动脚本中,标准的输出流指向<CATALINA_HOME>/logs/Catalina.out文件。
▲ SystemOutLogger的实现类是
org.apache.cataline.logger.SystemOutLogger,它把日志信息输出到Tomcat服务器指定的标准输出流中。在默认的Tomcat的启动脚本中,标准输出流指向<CATALINA_HOME>/logs/Catalina.out文件。
Tomcat阀(Valve)能够对Catalina容器接收到的HTTP请求进行预处理。Tomcat阀可以加入到3种Catalina容器中,它们是Engine、Host和Context。Tomcat阀在不同的容器中作用不同,具体作用参见下表:
容器 |
描述 |
Engine |
加入到Engine中的Tomcat阀可以预处理该Engine接收到的所有HTTP请求。 |
Host |
加入到Host中的Tomcat阀可以预处理该Host接收到的所有HTTP请求。 |
Context |
加入到Context中的Tomcat阀可以预处理该Context接收到的所有HTTP请求。 |
所有的Tomcat阀都实现类org.apache.Catalina.Valve接口或扩展了org.apache.Catalina.valves.ValvesBase类。Tomcat阀分为4种,分别是:
● 客户访问日志阀(Access Log Valve)
● 远程地址过滤器(Remote Address Filter)
● 远程主机过滤器(Remote Host Filter)
● 客户请求记录器(Request Dumper)
客户访问日志阀能够将客户的请求信息写道日志文件中。这些日志可以记录网页的访问次数、用户的会话活动和用户验证信息等。客户访问日志阀可以加入到Engine、Host和Context容器中,记录所在容器接收到HTTP请求信息。
客户访问日志阀的<Valve>元素的属性描述参见下表:
属性 |
描述 |
className |
指定阀的实现类,这里为org.apache.catalina.valves.AccessLogValve |
directory |
设定存放在日志文件的绝对或相对于<CATALINA_HOME>的相对目录。该属性的默认值为<CATALINA_HOME>/logs |
pattern |
设定日志的格式和内容。 |
Prefix |
设定日志文件名的前缀,默认值为access_log |
resolveHosts |
如果设为true,表示把远程IP地址解析为主机名;如果设为false,表示直接记录远程IP地址,默认值为false。 |
suffix |
设定日志文件的扩展名。 |
<Valve>元素的 pattern属性用于设定日志的格式和内容,它有以下可选值:
● %a :远程IP地址
● %A :本地IP地址
● %b :发送到字节数,不包括HTTP Header。-表示发送字节为0。
● %B :发送到字节数,不包括HTTP Header
● %h :远程主机名
● %H :客户请求所用的协议
● %l :远程逻辑用户名(目前总是返回-)
● %m :客户请求所用的方法(Get、Post等)
● %p :接收到客户请求的本地服务器端口
● %q :客户请求中查询字符串(Query string),如果存在,以?开头
● %r :客户请求的第一行内容(包括客户请求所用的方法以及请求的 URL)
● %s :服务器响应的结果中HTTP的状态代码
● %S :用户Session ID
● %t :时间和日期
● %u :经过安全验证的远程用户名。-表示不存在远程用户名
● %U :客户请求的URL路径
● %v :本地服务器名
例如在server.xml中localhost的<Host>元素中加入如下<Valve>元素:
<Valve className=” org.apache.catalina.valves.AccessLogValve”
Directory=”logs” prefix=”localhost_log.” Suffix=”.txt”
Pattern=”%h%l%u%t%s%b” resolveHost=”true”>
远程地址过滤器(Remote Address Filter)可以根据远程客户的IP地址来决定是否接受客户的请求。在远程地址过滤器中,事先保存了一份被拒绝的IP清单和允许访问的IP地址清单,如果客户端IP地址在拒绝清单中,那么这个客户的请求不会被Catalina容器响应。
远程地址过滤器(Remote Address Filter)元素的的属性描述如下:
属性 |
描述 |
className |
指定阀的实现类,这里是org.apache.catalina.valve.RemoteAddrValve. |
allow |
指定允许访问的客户IP地址,如果此项没有设定,表示只要客户IP地址不在deny清单中,就允许访问,多个IP以逗号隔开。 |
Deny |
指定不允许访问的客户IP地址,多个IP地址以逗号隔开。 |
例如在server.xml中localhost的<Host>元素中加入如下<Valve>元素:
<Valve className=” org.apache.catalina.valve.RemoteAddrValve”
Deny=”127.*,222.*”>
远程主机过滤器(Remote Host Filter)可以根据远程客户的主机名,来决定是否接受客户端请求。
远程主机过滤器(Remote Host Filter)的<Valve>元素的属性参见下表:
属性 |
描述 |
className |
指定阀的实现类,这里是org.apache.catalina.valve.RemoteHostValve. |
allow |
指定允许访问的客户主机名,如果此项没有设定,表示只要客户主机名不在deny清单中,就允许访问,多个主机名以逗号隔开。 |
Deny |
指定不允许访问的客户主机名,多个主机名以逗号隔开。 |
例如在server.xml中localhost的<Host>元素中加入如下<Valve>元素:
<Valve className=” org.apache.catalina.valve.RemoteHostValve”
Deny=”monster*”>
客户请求记录器用于把客户请求的详细信息记录到日志文件中,这里的日志文件是在<Logger>元素中配置的,客户请求记录器是一个有效的跟踪工具,尤其是当HTTP请求中的Header或Cookie出来问题时,他可以跟踪客户请求的详细信息。
假定在server.xml中localhost的<Host>元素中已经配置了如下<Logger>元素:
<Logger className=”org.apache.catalina.logger.FileLogger”
Directory=”logs” prefix=”localhost_log.” Suffix=”.txt”
Timestamp=”true”/>
然后在server.xml中localhost的<Host>元素中加入如下<Valve>元素:
<Valve calssName=”org.apache.catalina.valves.RequestDumperValve”/>
重启Tomcat服务器,从浏览器端访问helloapp应用,此时在<CATALINA_HOME>/logs目录下会生成一个localhost_log.txt文件。
安全域是Tomcat内置的功能,在org.apache.catalina.Realm接口中声明了把这一组用户名、口令及所关联的角色集成到Tomcat中的方法。Tomcat5提供了4个实现这一接口的类,他们分别代表了4中安全域类型。
▲ 内存域(MemoryRealm):在初始化阶段,从XML文件中读取安全验证信息,并把他们以一组对象的形式存放在内存中。
▲ JDBC域(JDBCRealm):通过JDBC驱动程序访问存放在数据库中的安全验证信息。
▲ 数据源域(DataSourceRealm):通过JNDI数据源访问存放在数据库中的安全验证信息。
▲ JNDI域(JNDIRealm):通过JNDI provider访问存放在基于LDAP的目录服务器中的安全验证信息。
MenmoryRealm是实现Tomcat 6.0 Realm接口的简单示例。不是为生产使用的。在启动时,MemoryRealm从一个XML文件中加载所有的用户以及对应的角色,默认情况下从(CATALINA_HOME)/conf/tomcat-users.xml目录中加载文档。在Tomcat启动前,对这个文件的修改不会生效。
要配置MemoeryRealm,您需要创建在您的$CATALINA_HOME/conf/server.xml 文件中创建<Realm>元素,共包含以下属性:
属性 |
描述 |
className |
Realm实现的Java全名。这里必须为“org.apache.catalina.realm.MemoryRealm”。 |
digest |
使用非明文方式保存密码的摘要算法。java.security.MessageDigest可接受的所有算法都是合法的。详细信息请参考摘要算法一节。如果没有指定这个参数,密码以明文方式保存。 |
pathname |
包含合法用户名,密码和角色的XML文件的绝对或相对(相对于$CATALINA_HOME)路径名。关于文件的更多信息,请看后面的介绍。如果没有指定这个参数,路径为conf/tomcat-users.xml。 |
user文件(默认情况下是conf/tomcat-users.xml)必须是一个XML文件,根元素是<tomcat-users>。内部的元素为<user>,表示每一个合法的用户,元素中包含如下属性:
◎ name: 登录使用的用户名。
◎ password:用户登录使用的密码(如果digest属性没有设置,则为明文,否则使用摘要算法保存)。
◎ roles: 逗号分隔的用户拥有的角色名称列表。
例如:
<tomcat-users>
<user name="tomcat" password="tomcat" roles="tomcat" />
<user name="role1" password="tomcat" roles="role1" />
<user name="both" password="tomcat" roles="tomcat,role1" />
</tomcat-users>
MemoryRealm的行为符合以下规则:
1. 当Tomcat启动时,它从user文件中加载所有的用户和关联信息。在Tomcat重启前,对这个文件的任何修改都不生效。当用户第一次尝试访问受保护资源时,Tomcat 6.0请求Realm的authenticate()方法。
2. 一旦用户认证成功,用户(以及关联角色)在用户登录的的这段时间内都缓存在Tomcat中。(对于基于FORM的认证,表示直到session超时;对于BASIC认证,意味着直到用户关闭浏览器)。缓存用户不在session序列化时保存和恢复。
3. 管理users文件中的信息是您应用程序的职责。Tomcat不提供任何内置的功能来维护用户和角色。
JDBCRealm是tomcat 5对Realm接口的实现,它通过JDBC驱动程序访问关系数据库。它的遍历配置可以适应于您已有的表和列名,只要您的数据库接口符合下列规范:
l 必须有一张表,以下称作用户表,有包含Realm可以识别的所有合法用户名称的行。
l 用户表必须包含至少两列(如果您的应用程序需要更多列,也是可以的):
n 当用户登录时,Tomcat可以识别用户名。
n 当用户登录时,Tomcat可以识别用户密码。密码可以是明文也可以是摘要。
l 必须有一张表,以下称作用户角色表,包含关联特殊用户的每种合法角色的行。用户有0个,1个或多个角色都是允许的。
l 用户角色表必须包含至少两列(如果您的应用程序需要更多列也是可以的):
n Tomcat可以识别的用户名(和用户表中的相应值一致)。
n 用户关联的合法角色名。
需要以下步骤设置Tomcat使用JDBCRealm:
1. 创建以上描述中必须的表和列。
2. 配置使用Tomcat的用户名和密码,至少需要有只读权限(Tomcat不会修改表中数据)。
3. 拷贝JDBC驱动程序到$CATALINA_HOME/lib目录。注意只能识别jar文件。
4. 按照后文的描述在您的$CATALINA_HOME/conf/server.xml文件中设置<Realm>元素。
5. 重启Tomcat 。
属性名 |
描述 |
className |
Realm实现的java全名。在这里必须为“org.apache.catalina.realm.JDBCRealm”。 |
connectionName |
建立JDBC连接的用户名。 |
connectionPassword |
建立JDBC连接的密码。 |
connectionURL |
建立JDBC连接的URL。 |
digest |
使用非明文方式保存用户密码的摘要算法。只能输入java.security.MessageDigest支持的算法名称。如果不指定,密码以明文方式保存。 |
driverName |
使用的JDBC驱动程序全名。详细信息请查看您使用的JDBC驱动程序。 |
roleNameCol |
用户角色表中的角色名,包含赋予用户的角色。 |
userCredCol |
用户表中列名,包含用户的密码(可以是明文也可以是密文)。 |
userNameCol |
用户和用户角色表中的列表,包含了用户名。 |
userRoleTable |
用户角色表。表中必须有userNameCol和roleNameCol中指定的列。 |
userTable |
用户表。表中必须有userNameCol列。 |
例如:
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)
);
在默认的$CATALINA_HOME/conf/server.xml中加入了Realm属性。以下示例使用MySQL数据库,名称是“authority”,使用上述的表进行配置,用户名为“dbuser”,密码为“dbpass”:
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/authority?user=dbuser& password=dbpass"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
l 当用户第一次访问受保护的资源,Tomcat 5请求Realm的authenticate()方法。因此,您对数据库做的修改会立即生效。
l一旦用户认证成功,用户名和相关角色在用户登录后就缓存在Tomcat中。对于基于表单的认证,直到session超时时才会过期,对于基本认证,用户关闭浏览器后就会过期。在session序列化时不会进行缓存用户的保存和重置。对已授权用户的修改在用户下次登录前不会生效。
l 管理用户和用户角色表时是您应用程序的责任。Tomcat不提供任何内置的方法进行用户和角色表的维护。
DataSourceRealm是通过JNDI命名的JDBC数据源访问关系数据库的方式实现Realm接口的方式。这种方式的灵活性允许您使用已经存在的表和列名,只要数据库的结构符合以下需求即可:
l 必须有一张表,以下称作用户表,有包含Realm可以识别的所有合法用户名称的行。
l 用户表必须包含至少两列(如果您的应用程序需要更多列,也是可以的):
n 当用户登录时,Tomcat可以识别用户名。
n 当用户登录时,Tomcat可以识别用户密码。密码可以是明文也可以是摘要。
l 必须有一张表,以下称作用户角色表,包含关联特殊用户的每种合法角色的行。用户有0个,1个或多个角色都是允许的。
l 用户角色表必须包含至少两列(如果您的应用程序需要更多列也是可以的):
n Tomcat可以识别的用户名(和用户表中的相应值一致)。
n 用户关联的合法角色名。
按照如下方式设置DataSourceRealm:
1.创建以上描述中必须的表和列。
2.配置使用Tomcat的用户名和密码,至少需要有只读权限(Tomcat不会修改表中数据)。
3. 为您的数据库配置JNDI命名的JDBC数据源。详细信息请参考如何配置JNDI数据源。
4.按照后文的描述在您的$CATALINA_HOME/conf/server.xml文件中设置<Realm>元素。
5.重启Tomcat。
属性名 |
描述 |
className |
Realm实现的java全名。在这里必须为“org.apache.catalina.realm.DataSourceRealm”。 |
dataSourceName |
您应用程序JNDI命名的JDBC数据源。如果DataSource在本地上下文中,名称和java:/comp/env有关,否则名称需要符合定义全局DataSource的名称。 |
digest |
使用非明文方式保存用户密码的摘要算法。只能输入java.security.MessageDigest支持的算法名称。如果不指定,密码以明文方式保存。 |
localDataSource |
当Realm定以在Context元素之内,允许Realm使用Context定义的数据源,而不是全局数据源。如果没有这个参数,默认使用全局数据源。 |
roleNameCol |
用户角色表中的角色名,包含赋予用户的角色。 |
userCredCol |
用户表中列名,包含用户的密码(可以是明文也可以是密文)。 |
userNameCol |
用户和用户角色表中的列表,包含了用户名。 |
userRoleTable |
用户角色表。表中必须有userNameCol和roleNameCol中指定的列。 |
userTable |
用户表。表中必须有userNameCol列。 |
例如:
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 className="org.apache.catalina.realm.DataSourceRealm" debug="99"
dataSourceName="jdbc/authority"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
DataSourceRealm使用遵循下列规则:
l 当用户第一次访问受保护的资源,Tomcat 6 请求Realm的
authenticate()方法。因此,您对数据库做的修改会立即生效。
l 一旦用户认证成功,用户名和相关角色在用户登录后就缓存在Tomcat中。对于基于表单的认证,直到session超时时才会过期,对于基本认证,用户关闭浏览器后就会过期。在session序列化时不会进行缓存用户的保存和重置。对已授权用户的修改在用户下次登录前不会生效。
l 管理用户和用户角色表时是您应用程序的责任。Tomcat不提供任何内置的方法进行用户和角色表的维护。
JNDIRealm是通过JNDI提供者访问LDAP目录服务器的Realm接口实现(通常情况下,标准的LDAP提供者使用JNDI API就可以访问)。realm支持使用目录进行认证的多种手段。
使用connectionURL属性配置realm连接的目录。URL的格式由JNDI提供者定义。通常是一个LDAP URL指定了目录服务器的域名,同时指定了端口号以及需要的根名称上下文的DN。
如果有多于一个提供者,可以配置alternateURL参数.如果socket不能连接到connectionURL指定的URL,可以尝试连接alternateURL。
当创建一个连接查询目录并且获取用户和角色信息时,realm通过connectionName和connectionPassword属性提供的用户名和密码在目录服务器中进行认证。如果没有提供这些属性,连接是匿名的。有时这就足够了。
每个可以通过认证的用户在目录中都有独立的入口,对应初始化DirContext中的一个元素,使用connectionURL属性定义。用户目录必须有一个属性包含认证用的用户名。
通常,用户入口的DN包含认证用的用户名,除这个之外所有用户其他内容相同。在这种情况下,userPattern属性可以指定DN,使用“{0}”标记表示用户名应该被替换。
否则,realm必须搜索目录得到包含用户名的单一入口。以下的配置支持这种搜索:
l userBase:
这个目录是包含用户信息的子树的根目录。如果没有指定,根目录是上下文的最上层。
l userSubtree:
搜索范围。设置为true表示将搜索根目录为userBase的整个子树。初始值为false,表示只搜索最顶层。
l userSearch:
LDAP搜索过滤器的模式,用来进行用户名的替换。
l 绑定模式
默认情况下,realm通过使用DN入口绑定到目录的用户名和密码进行认证。如果简单的绑定成功,认为用户已经授权。
安全起见,目录中保存用户密码的摘要而不直接保存明文。如果是那样的话,在与目录中保存的值比较之前,自动计算用户输入密码的摘要值,成为简单绑定的一部分。在绑定模式中,realm不包含摘要处理。所以不应该使用digest属性,实际处理时也会忽略这个属性。
l 比较模式
可选的,realm可以从目录中取出密码,然后直接和用户的输入进行比较。这种模式通过设置userPassword属性实现,属性值是用户入口中包含用户密码的目录属性名。
比较模式有一些不足。首先,必须配置connectionName和connectionPassword属性,允许realm从目录中读取用户的密码。处于安全考虑一般不使用这种方式,实际上,一些目录的实现甚至不允许目录的管理员读取密码。另外,realm必须自己处理密码摘要,包括多种加密算法以及密码的哈希值的在目录中的表示方式。然而,有时realm可以访问密码,例如支持HTTP摘要访问认证(RFC 2069)。(注意,HTTP摘要认证和以上描述的将用户密码摘要保存在仓库中不一样)。
目录realm支持两种方式表示目录中的角色:
l 角色作为显式的目录入口
角色可以使用显式的目录入口表示。角色入口一般是LDAP组入口,其中一个属性包含角色的名称,另一个属性是DN或拥有这个角色的用户名。以下属性配置了查询角色关联认证用户的方法:
n roleBase
查询角色的根入口。如果没有指定,从目录上下文的最上层开始搜索。
n ruleSubtree
搜索范围。如果您向搜索roleBase入口指定的整个子树,设置这个参数为true。默认情况下这个参数为false,表示只搜索最上层。
n roleSearch
LDAP搜索过滤器的模式,用来进行用户名的替换。
n roleName
角色入口中包含角色名称的属性。
l 将角色作为用户入口的属性之一
角色名可以当作用户目录入口的一个属性保存,属性名为userRoleName。
两者可以同时使用。
按照如下方式设置JNDIRealm:
1.按照上述要求配置目录服务器的模式。
2. 配置被使用Tomcat的用户名和密码,至少需要有只读权限(Tomcat不会修改表中数据)。
3.将JDNI启动程序拷贝到$CATALINA_HOME/lib目录下。
4.按照后文的描述在您的$CATALINA_HOME/conf/server.xml文件中设置<Realm>元素。
5.重启Tomcat
Realm元素属性
要配置JNDIRealm,需要在$CATALINA_HOME/conf/server.xml文件中创建<Realm>元素。以下是这个实现支持的参数:
属性名 |
描述 |
className |
Realm实现的java全名。在这里必须为“org.apache.catalina.realm.JNDIRealm”。 |
connectionName |
建立JDBC连接的用户名。 The directory username to use when establishing a connection to the directory for LDAP search operations. If not specified an anonymous connection is made, which is often sufficient unless you specify the userPassword property. |
connectionPassword |
建立JDBC连接的密码。 |
connectionURL |
建立JDBC连接的URL。 |
digest |
使用非明文方式保存用户密码的摘要算法。只能输入java.security.MessageDigest支持的算法名称。如果不指定,密码以明文方式保存。 |
driverName |
使用的JDBC驱动程序全名。详细信息请查看您使用的JDBC驱动程序。 |
roleNameCol |
用户角色表中的角色名,包含赋予用户的角色。 |
userCredCol |
用户表中列名,包含用户的密码(可以是明文也可以是密文)。 |
userNameCol |
用户和用户角色表中的列表,包含了用户名。 |
userRoleTable |
用户角色表。表中必须有userNameCol和roleNameCol中指定的列。 |
userTable |
用户表。表中必须有userNameCol列。 |
如何在目录服务器中创建正确的架构已经不再本文的范围内,因为这个操作独立于目录服务器的实现。在下面的例子中,假设您使用OpenLDAP目录服务器(2.0.11或以后版本),可以从http://www.openldap.org下载。假设您的slapd.conf文件中有如下配置:
database ldbm suffix dc="mycompany",dc="com" rootdn "cn=Manager,dc=mycompany,dc=com" rootpw secret |
假设目录服务器和Tomcat安装在同一台机器中。关于使用JNDI LDAP提供者的详细信息请参见http://java.sun.com/products/jndi/docs.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: [email protected] 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: [email protected] 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 |
按照上述OpenLDAP目录服务器配置的realm元素应该如下所示,假设用户使用uid登录应用程序,同时匿名连接已经能够进行目录的查询以及从目录中获取角色信息:
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99" 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})"/> |
使用这种配置,realm可以通过在userPattern中替换用户名的方法决定用户的DN,然后通过将DN以及用户密码和目录绑定,查询用户的角色。
现在假设用户向通过输入email地址的方式进行登录。这样realm必须查询目录中的用户项。(当用户的入口放置在多个子树中,可能对应不同的组织集团或公司)。
更进一步,假设除了使用组条目外,您想使用用户条目的一个属性保存角色。Janet Jones的条目可能如下所示:
dn: uid=jjones,ou=people,dc=mycompany,dc=com objectClass: inetOrgPerson uid: jjones sn: jones cn: janet jones mail: [email protected] memberOf: role2 memberOf: role3 userPassword: janet |
这种realm配置将会满足新的需求:
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99" 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使用“[email protected]”进行登录时,realm在目录中查询有mail属性为这个值的唯一条目,然后尝试使用给定的密码绑定到目录“uid=jjones,ou=people,dc=mycompany,dc=com”中。如果认证成功,她就拥有了以下权限:“role2”和“role3”,她的目录条目中的“memberOf”属性。
最后,通过从目录中获取密码然后在realm中进行认证,需要如下的realm配置:
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99" 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使用遵循下列规则:
l 当用户第一次访问受保护的资源,Tomcat 6 请求Realm的authenticate()方法。因此,您对数据库做的修改会立即生效。
l 一旦用户认证成功,用户名和相关角色在用户登录后就缓存在Tomcat中。对于基于表单的认证,直到session超时时才会过期,对于基本认证,用户关闭浏览器后就会过期。在session序列化时不会进行缓存用户的保存和重置。对已授权用户的修改在用户下次登录前不会生效。
l 管理用户和用户角色表时是您应用程序的责任。Tomcat不提供任何内置的方法进行用户和角色表的维护。
Tomcat既可以运行采用开放式目录结构的Web应用,也可以运行WAR文件。只要把整个helloapp目录拷贝到/webapps目录下,即可运行开放式目录结构的helloapp应用。在Web应用的开发阶段,为了便于调试,通常采用开放式的目录结构来发布Web应用,这样可以方便地更新或替换文件。如果开发完毕,进入产品发布阶段,应该将整个Web应用打包为WAR文件,再进行发布。
在本例中,按如下步骤发布helloapp。
(1)进入helloapp应用的根目录/webapps/helloapp。
(2)把整个Web应用打包为helloapp.war文件,命令如下:
jar cvf helloapp.war *.*
在JDK的bin目录下提供了打包程序jar.exe。如果要展开helloapp.war文件,命令为:
jar xvf helloapp.war
(3)把helloapp.war文件拷贝到/webapps目录下。
(4)删除原先的helloapp目录。
(5)启动Tomcat服务器。
Tomcat服务器启动时,会把webapps目录下的所有WAR文件自动展开为开放式的目录结构。所以服务器启动后,会发现服务器把helloapp.war展开到 /webapps/helloapp目录中。
在Tomcat的配置文件server.xml中,Host元素代表虚拟主机,在同一个Engine元素下可以配置多个虚拟主机。例如,有两个公司的Web应用都发布在同一个Tomcat服务器上,可以为每家公司分别创建一个虚拟主机,它们的虚拟主机名分别为:
www.mycompany1.com
www.mycompany2.com
这样当Web客户访问以上两个Web应用时,就好像这两个应用分别拥有各自的主机。此外,还可以为虚拟主机建立别名,例如,如果希望Web客户访问www.mycompany1.com或mycompany1.com都能连接到同一个Web,那么可以把mycompany1.com作为虚拟主机的别名来处理。
下面讲解如何配置www.mycompany1.com虚拟主机。
(1)打开/conf/server.xml文件,会发现在元素中已经有一个名为localhost的元素,可以在它的后面(即后面)加入如下元素:
<Host name="www.mycompany1.com"
debug="0" appBase="C:\mycompany1"
unpackWARs="true" autoDeploy="true">
<alias>mycompany1.com</alias>
<alias>mycompany1</alias>
<Context path="/helloapp"
docBase="helloapp" debug="0"
reloadable="true" />
</Host>
<Host> 元素的属性如下:
属 性 描 述 |
|
name |
指定虚拟主机的名字 |
debug |
指定日志级别 |
appBase |
指定虚拟主机的目录,可以指定绝对目录,也可以指定相对于的相对目录。如果此项没有设定,默认值为/webapps |
unpackWARs |
如果此项设为true,表示将把Web应用的WAR文件先展开为开放目录结构后再运行。如果设为false,则直接运行WAR文件 |
autoDeploy |
如果此项设为true,表示当Tomcat服务器处于运行状态时,能够监测appBase下的文件,如果有新的Web应用加入进来,则会自动发布这个Web应用 |
alias |
指定虚拟主机的别名,可以指定多个别名 |
deployOnStartup |
如果此项设为true,则表示Tomcat服务器启动时会自动发布appBase目录下所有的Web应用。如果Web应用在server.xml中没有相应的元素,则将采用默认的Context配置。deployOnStartup的默认值为true |
在的deployOnStartup属性为true的情况下,即使你没有在server.xml中为helloapp应用加入元素,Tomcat服务器也可以自动发布和运行helloapp应用。
在这种情况下,Tomcat使用默认的DefaultContext。关于DefaultContext的知识可以参考Tomcat文档:
/webapps/tomcat-docs/config/defaultcontext.html
(2)把helloapp应用(helloapp.war文件或者是整个helloapp目录)拷贝到appBase属性指定的目录C:\mycompany1下。
(3)为了使以上配置的虚拟主机生效,必须在DNS服务器中注册以上的虚拟主机名和别名,使它们的IP地址都指向Tomcat服务器所在的机器。必须注册以下名字:
www.mycompany1.com
mycompany1.com
mycompany1
(4)重启Tomcat服务器,然后通过浏览器访问:http://www.mycompany1.com/helloapp/index.htm,如果返回正常的页面就说明配置成功。还可以通过虚拟机的别名来访问helloapp应用:
http://mycompany1.com/helloapp/index.htm
http://mycompany1/helloapp/index.htm