通过代码示例学习Java安全技术(第7部分:Tomcat服务器对J2EE安全规范的支持)
前言
随着网络应用的不断深入,特别是电子商务应用的普及,对网络应用的安全提出了许多新的和更高的要求。在Java及J2EE应用系统平台环境中,提供了多层次和多种形式的安全技术的支持,从而可以在一定的程度上保证应用系统的安全性。比如,将Web应用中的客户端和Web服务器端之间的通讯连接方式从Http方式改变为Https方式,则是对Web 应用在协议层次的安全保护技术——Https是在协议层对Http的再次封装,加入了SSL/TLS等相关的技术。
作者根据自身多年的软件开发实践和经验总结,结合多年的IT职业培训的教学和高校软件学院一线的教学工作体验,在本系列文档中通过具体的程序代码示例为读者介绍Java 及J2EE应用系统平台环境中的安全相关的应用技术。主要的目的是希望能够将作者在项目开发中所涉及的安全应用技术进行总结和提炼,以成功的经验或者失败的教训为读者减少软件开发中由于安全技术的欠缺而导致应用系统在使用中所带来的各种风险,同时也为高校师生总结出Java及J2EE应用系统平台环境中的相关安全技术,增强和培养软件专业的学生对应用系统安全技术的关注度和提高对相关技术的应用能力。
在J2EE的技术规范中,为J2EE应用系统提供了两种不同形式的安全控制规范:说明性的安全性和可编程的安全性。本示例文档将应用“说明性的安全性”实现对Web应用的安全进行定义。
所谓的说明性的安全性,也就是通过安全结构描述(一般是在XML配置文件中定义)的方式来代表应用程序的安全需求。安全结构一般包括安全角色、访问控制和验证要求等方面的信息。在J2EE平台中的Web应用程序中的部署描述符文件(web.xml)充当了说明性安全的主要定义工具。因为部署描述符web.xml文件是Web应用系统组件的开发者和应用程序部署者或应用程序组装者之间的配置定义工具。
本文档主要涉及J2EE安全性相关知识,在Tomcat服务器中如何实现Http可配置化验证技术及应用示例,包括Http基本身份验证示例、自定义表单身份验证的示例和Http摘要身份验证的示例等方面的内容。通过这些应用示例,为读者介绍在Web应用系统的开发中如何实现将应用系统中的身份验证逻辑处理程序从Web应用中分离并由服务器提供实现。
杨教授大学堂精心创作有系列化的优秀程序员职业提升必读技术资料,这些资料将系统地从软件设计和开发实现的“设计思想”、“管理策略”、“技术实现”和“经验方法”等方面与读者进行充分的交流,涉及作者对软件开发设计思想和原则、课程设计、项目实训、软件实现技术等方面的学习心得体会和应用技巧、经验总结。
本文目录
1.1Tomcat中实现Http可配置化验证 (3)
1.1.1在web.xml文件中与身份验证相关的标签 (3)
1.1.2在Tomcat中实现基本的Http身份验证示例 (10)
1.2在Tomcat中实现自定义表单身份验证 (18)
1.2.1基于自定义表单的验证技术及应用 (18)
1.2.2在Tomcat中实现自定义表单身份验证的示例 (20)
1.2.3对Struts框架中的Action程序进行授权 (26)
1.3在Tomcat中实现摘要身份验证 (27)
1.3.1Http 摘要身份验证 (27)
1.3.2在Tomcat中实现摘要身份验证的示例 (28)
1.1Tomcat中实现Http可配置化验证
1.1.1在web.xml文件中与身份验证相关的标签
1、web.xml文件的作用
web.xml系统配置文件是按照J2EE Servlet规范定义的Web应用发布描述符文件,是完全独立于Tomcat Servlet容器的Web应用本身的配置信息文件。主要是用来初始化Web应用中的各种配置信息:比如Welcome页面、Servlet、Servlet-Mapping、Filter、Listener、启动加载级别等方面的配置信息。
当然,如果在Web应用中没有涉及这些配置信息时,可以不用web.xml文件。因此,对于每个Web 项目来说,web.xml文件并不是必须要提供的。如下为某个Web项目中的web.xml文件的存储位置的示图。
在J2EE的Web应用中,Web容器(Servlet容器)支持Web应用程序内置的安全机制——身份认证和访问授权。
2、J2EE安全性相关知识介绍
在J2EE的技术规范中,为J2EE应用系统提供了两种不同形式的安全控制规范:说明性的安全性和可编程的安全性。本示例文档将应用“说明性的安全性”实现对Web应用的安全进行定义。
(1)说明性的安全性
通过安全结构描述的方式来代表应用程序的安全需求,安全结构一般包括安全角色,访问控制和验证要求等。在J2EE平台中的Web应用程序中的部署描述符文件(web.xml)充当了说明性安全的主要定义工具。
因此,部署描述符web.xml文件是Web应用系统组件的开发者和应用程序部署者或应用程序组装者
之间的配置定义工具。应用程序的开发者用它来表示应用中的安全需求,应用程序部署者或应用程序组装者将安全角色与部署环境中的用户和组映射起来。
在Web应用程序运行时,容器(Web容器和EJB容器)从部署描述符web.xml文件中提取出相应的安全策略,然后容器(Web容器和EJB容器)根据安全策略执行安全验证。因此,应用说明性的安全性验证技术,不需要开发人员编写任何的安全相关的程序代码,一切都是通过配置部署描述符web.xml 文件定义。
(2)可编程的安全性
可编程的安全性是在说明性的安全技术的基础上,使安全敏感的应用可以通过调用被容器(Web容器和EJB容器)提供的API来对安全作出决断。这在说明性的安全性不足以满足企业的安全模型的情况是非常有用的。比如J2EE在Servlet的HttpServletRequest 接口中提供有两个如下的方法:isUserInRole (HttpServletRequest):判断用户角色
getUserPrincipal (HttpServletRequest):获得用户认证信息principal
3、Web容器提供三种类型的认证机制
(1)可配置化的安全验证技术
这些认证机制都允许开发人员直接在Web应用程序中的web.xml配置文件中进行相关的配置就可以实现Web应用的登录验证方面的功能,从而减少了对系统登录功能实现的重复编程开发,而且灵活性比较高——可以根据应用的需要随时改变相关的配置项目。
(2)定义受保护的资源和授权角色
开发人员可以把Web应用中受保护的各种资源都定义在web.xml配置文件的资源集的定义标签(如
1)基本认证(BASIC)
2)基于表单的认证(Form)
3)摘要认证(DIGEST)
(4)为什么要应用JAAS的Java验证和授权服务
使用JAAS(Java Authentication Authorization Service,Java验证和授权服务)验证的好处是,身份验证的逻辑处理程序从Web页面中分离,对页面的限制访问是通过在/WEB-INF/web.xml文件中的配置标签定义和指定,无需自行编程相关的身份验证的处理程序。
4、Http基本认证(BASIC)方式
(1)基本认证方式是HTTP1.0标准中所提出的认证方法
它被认为是最不安全的认证。因为它不仅没有提供对用户提交的身份信息在传递到服务器端程序的加密保护的相关措施,而且身份验证的页面也不能按照用户的要求进行定制以满足用户的特殊应用要求。
(2)配置定义示例
如下为定义基本认证方式的标签——由其中的
(3)身份认证界面
当用户试图访问受保护的系统资源时,浏览器将会弹出如下示图所示的对话框,用户在其中的“用户名”和“密码”输入框中输入相关的身份信息;如果身份验证通过,则将进入受保护的资源页面,否则将继续进行身份验证。
(4)主要的缺点
基本认证方式的主要缺点是用户名和密码等信息都是用Base64 编码转换之后传输到Web容器的——而Base64编码本身非常容易被解码,所以经过base64编码的密码实际上是明文发送的。可以被拦截和获得用户提交的身份信息;此外,客户端浏览器也还无法认证Web服务器的合法性,因此客户端用户很容易被钓鱼到一个非法的Web服务器从而输入了身份信息。因此,存在一定的安全隐患。
5、Http基于表单的认证(Form)
(1)基于表单的认证其实也就是自定义表单的认证
开发人员可以指定用户身份验证登录时的验证表单所在页面和登录失败时所跳转的错误信息显示
页面。因为在Htpp基本认证方式中所弹出的身份验证的界面是浏览器内带的登录表单,为了统一登录界面和Web应用中的其它页面保持一致的界面风格,可以应用Http自定义表单的认证。
(2)配置定义示例
如下的标签示例为基于表单认证的配置定义:
其中的
6、Http摘要认证(DIGEST)
(1)它是HTTP1.1提出的对前面的基本认证的替代方法
相比于前面的基本(BASIC)认证方式和基于表单的认证(Form),它是相对比较安全的认证方式。因为在认证时将请求的数据要通过MD5的加密方式提取出明文密码的信息摘要,而其它两种身份验证下的用户账号和密码等请求信息都是以明文的形式在网络上传输。
(2)配置定义示例
如下的标签示例为DIGEST认证的配置定义:
(3)身份认证界面
当访问者试图访问受保护的系统资源时,浏览器将会弹出如下示图所示的身份验证的表单(其实为对话框)。
7、为什么要应用Web容器所提供的身份认证机制
(1)什么是身份认证
身份认证是在计算机网络信息通讯过程中确认信息的发送方和信息的接收方双方身份的过程,以正确地区分信息的发送方和信息的接收方。
身份认证在目前的Web应用系统环境中可分为用户(客户端系统的使用者)与服务器主机间的认证和服务器主机与主机之间(分布式网络应用环境)的认证两种主要的形式。
(2)什么是访问控制
访问控制可以确保安全角色只能访问已授予它安全权限的授权对象。当然,在企业级的应用系统中,最为普遍采用的访问控制机制是基于角色的访问控制(Role Based Access Control,简称RBAC)。
读者需要注意的是,J2EE系统平台中的角色机制与标准的RBAC是有很大的差别,同时自身也存在一定的缺陷。比如,J2EE的角色仅仅是一组权限声明的集合,并且不具有继承关系、约束关系,也不能在运行时对角色和权限进行动态的管理——因为容器管理的安全中的用户角色是在Web应用程序部署描述符web.xml文件中预先定义并静态地映射到在目标J2EE 容器中所定义的安全角色。
(3)为什么要应用身份认证的管理机制
在IT业中的一切信息(当然,也包括用户的身份信息)都是用一组特定的数据表示的,而计算机目前只能识别出用户的数字身份而无法准确地识别出用户的实际物理、社会身份。此外,在企业应用环境中的某些资源往往要求只允许某些人访问,有些资源甚至是机密的或安全敏感的。
因此,在IT应用中如何保证以数字身份进行操作的IT设备使用者就是这个数字身份所定义的合法拥有者或者使用者,从而保证操作者的物理身份与对应的数字身份是相互对应的?
身份认证机制及相关的实现技术其实也就是解决这类问题的,从而避免不良后果的产生;对企业应用系统中的各种Web资源进行访问控制也是十分必要的。
8、Web应用中的登录是最常见的身份验证形式
(1)应用系统一般都提供有身份登录验证的程序界面
在许多Web应用系统中,特别是企业应用系统中都提供有登录的操作界面——可以为登录的Web
表单页面,也可以为应用程序的对话框。当应用系统的使用者试图访问敏感的系统资源或者使用相关的功能时,应用系统一般都会弹出身份登录验证的程序界面。
(2)重复地开发实现身份登录验证的界面及相关程序
为此,软件系统的开发实现人员也就必须要在每个应用系统中都要重复地开发实现登录功能模块。这在一定的程度上会导致开发工作的重复性,能否由相关的系统平台统一实现登录界面和身份信息的验证检查?
J2EE Web容器中所提供的身份认证机制其实就是帮助J2EE系统平台下的开发人员解决此类问题,减少相关的开发人员的重复工作;另外,将应用系统中的所有访问控制的决策都委托给J2EE容器,从而将应用系统中的业务处理逻辑与安全定义和技术实现进行分离。
9、web.xml文件中的
(1)
它定义基于Web容器的身份验证方式,如果为表单的验证方式,则还可以定义登录表单所在页面的URI、登录失败时的错误信息显示的页面等方面的信息。
(2)
(3)
下面配置示例中的
其中的
10、web.xml文件中的
(1)
它为“安全约束”方面的定义,主要定义Web应用系统中的那些系统资源需要被保护和可访问的用户类型等方面的信息,Web容器将使用在web.xml配置文件中定义的安全角色(由
(2)
(3)
下面的配置示例由
而其中的
1.1.2在Tomcat中实现基本的Http身份验证示例
1、在tomcat-users.xml文件中定义用户和角色
(1)tomcat-users.xml文件所在的目录
可以在C:\jakarta-tomcat-5.0.19\conf(为本示例的Tomcat服务器的相关目录)下的tomcat-users.xml 文件中添加Web应用相关的角色和用户账号。如下示图为tomcat-users.xml文件所在的目录的局部截图。
(2)tomcat-users.xml文件的主要作用
Tomcat采用基于角色的访问控制模型管理用户对系统的使用,安全性比较高,其角色和对应用户都保存在tomcat-users.xml中。在tomcat-users.xml文件中所定义的内容是不依赖于任何一个Web应用程序的,可以在任何一个Web程序中都可以使用在tomcat-users.xml文件中所定义的信息——因此,其中的信息是全局配置信息。
在tomcat-users.xml文件中一般定义用户的角色类型、某个角色中所包含的各个用户的身份信息(账号和密码)。
(3)在tomcat-users.xml文件中可以同时添加多类和多个用户
在tomcat-users.xml文件开头声明了XML的版本和编码方式,而其中的
当然,一个用户也可以拥有多个不同角色的权限,如其中的
tomcat-users.xml文件具有扩充性,开发人员可以在其中根据应用的需要增加新的角色和用户账号等身份信息。
在本示例中通过增加如下的新的配置标签示例以定义角色名称为users,其中包含有两个用户——yang和zhang,以及这些账号所对应的密码。
(4)什么是角色和为什么要应用角色
角色一方面代表一系列用户,另外一方面也可以代表一系列的权限。因此,角色是用户和权限的结合体。引入角色的概念主要是为了分离用户和访问权限的直接联系。
因为用户与访问权限的直接组合可能是短暂的,而角色则可以相对稳定。用户的变化只涉及到角色而无需考虑权限。而权限的变化只涉及到角色,也无需考虑用户或用户组。
2、然后在Web应用的web.xml文件中定义被保护的资源并对该资源进行访问授权
(1)定义被保护的资源URI
如下标签中的
protected Resource
(2)对该资源进行授权
上面的示例标签中的
3、在Web应用的web.xml文件中定义验证的方式
主要是要决定身份验证的方式——基本验证还是表单验证等,如下的配置定义示例选择基本验证方式。
4、在Web应用的web.xml文件中定义安全角色
其中的
5、完整的配置定义标签示例
"https://www.360docs.net/doc/269243307.html,/dtd/web-app_2_3.dtd">
…..
protected Resource
…..
6、Tomcat提供Realm支持
(1)什么是Realm(安全域)
Tomcat服务器使用Realm使某些特定的用户组具有访问某些特定的Web应用的权限,而没有权限的用户不能访问这个应用。Realm类似于Unix操作系统中的Group(组)——在Unix操作系统中,一个Group对应着操作系统中的一定资源,某个Group不能访问不属于它的系统资源。
安全域(Realm)是Tomcat服务器用来保护Web应用中的相关敏感资源的一种机制。开发人员在安全域中可以配置安全验证方面的信息——即用户信息(包括用户名和口令)以及用户和角色的映射关系。在Tomcat服务器中的org.apache.catalina.Realm接口中声明了把一组用户名、口令及所关联的角色集成到Tomcat中的方法,为部署在Tomcat服务器中的Web应用程序提供安全性的技术实现的支持。(2)Tomcat提供了如下不同Realm对访问某个Web应用程序的用户进行相应的验证1)JDBCRealm(JDBC域)
JDBCRealm通过JDBC驱动程序访问存放在关系型数据库中的安全认证信息,因此它是将用户的身份信息存放在数据库表中,并通过JDBC API从数据库表中获得用户身份信息并进行身份验证。
JDBC域使得安全配置非常灵活。当修改了数据库中的安全认证信息后,不必重启Tomcat服务器——因为数据库系统和Tomcat服务器两者是相互独立的。
当用户第一次访问受保护的资源时,Tomcat将调用Reaml的authenticate()方法,该方法从数据库中读取最新的安全认证的身份信息。该用户通过认证之后,在用户访问Web资源期间,用户的各种验证信息被保存在缓存中。
2)DataSourceRealm(数据库连接池域)
DataSourceRealm域和JDBCRealm域的两者的不同是访问数据库的方式不一样:DataSourceRealm 通过Tomcat服务器容器所提供的JNDI类型的DataSource(数据库连接池)访问数据库,而JDBCRealm 则是通过JDBC驱动程序操作访问数据库。
DataSourceRealm采用数据库连结池机制,把可用的数据库连结保存在缓存中,避免每次访问数据库都建立数据库连结,这样可以提高访问数据库的效率。
3)JNDIRealm(JNDI Directory 域)
将用户信息存在基于LDAP等目录服务的服务器里,通过JNDI技术从LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议)服务器中获取用户的身份信息并进行验证。
4)MemoryRealm(内存域)
将用户信息存在一个XML配置文件中,对用户进行身份验证时,将会从相应的XML配置文件(默认情况下,该XML文件为Tomcat安装目录的conf/tomcat_users.xml文件)中提取用户信息。内存域是由org.apache.catalina.realm.MemoryRealm类来实现的,在Web应用初始化阶段,Tomcat服务器从XML 文件中读取安全认证信息,并把它们以一组对象的形式存放在内存中。
但如果修改身份信息的XML文件后,则需要重新启动Tomcat服务器。
5)JAASRealm(JAAS)
通过JAAS(Java Authentication Authorization Service,Java验证和授权API)的安全授权API,实现自己的安全认证机制。开发人员可以通过实现以下的两个接口:javax.security.auth.spi.LoginModule 和javax.security.Principal从而实现自己的安全机制。
(3)本示例应用
7、测试本配置示例的执行效果
(1)试图访问受保护的系统资源
重新启动Tomcat服务器,并在浏览器中直接输入在Web应用系统中所保护的资源所在的目录的请求URL地址:http://127.0.0.1:8080/WebMis/BasicV erify/,将出现如下的登录页。
(2)身份验证成功后将可以访问受保护的系统资源
在弹出的登陆身份验证的表单中输入用户名称:yang(请见前面的tomcat-users.xml文件的设置的各个用户的账号),密码:12345678后将出现如下的信息页面——也就是能够正常地看到和访问受保护的系统资源。
而如果用户名称或者密码出现错误而导致身份验证失败时,浏览器将强制要求用户再次输入身份信息并且只有在登录成功后,访问者才能访问到被保护的目标资源,否则将一直处在系统登录的状态。
8、了解Http基本验证方式的请求响应的过程
Http认证采用“质询—响应(Challenge-Response)”的机制,其中的“质询”是Web服务器端对客户端的质询,即要求客户端程序发送身份认证相关的信息;而所谓的“响应”是客户端程序对Web服务器端程序的“质询”的响应,即发送带有认证信息的Http请求。
在各种Http认证方式中的客户端程序(如Web浏览器)第一次请求一个URI资源时,并不知道该资源是否需要进行身份认证,因此总是不带认证信息的发送请求,这时的Web服务器端程序就会找不到相关的认证信息,从而导致此次的认证失败,于是向客户端程序发出一个“质询”(给客户端发送一个Http响应,其状态码为401(Unauthorized),并且包含消息头WWW-Authenticate)。
(1)客户端浏览器请求某个受保护的系统资源后,Web服务器接收到该请求的URL地址后会发送一个401(未授权)的Http响应信息,在响应信息中附带有Realm信息表示此请求的目标资源是要使用Basic 认证——要求客户端提供用户名和密码进行身份认证。
(2)客户端浏览器接收到这个401的响应信息后,会按照协议的要求弹出一个登录的对话框——也就是前面的登录表单。强制要求用户输入用户名和密码等信息。并在用户点击“确定”按钮后提交用户名、密码到Web服务器——但会将输入的用户名密码用Base64进行编码转换后,采用非加密的明文方式传送给服务器。
提交的方式是在Http的请求头中加入:WWW-Authorization:Basic XXXXXXX。其中的Basic后面的信息是用户名、密码的BASE64的编码——也就是客户端浏览器收到“质询”后,需要给Web服务器端程序返回一个“响应”。为此,需要重新发送一个新的Http请求。这个新的Http请求与前一个Http 请求的差别在于多了一个Authorization消息头。
(3)如果认证成功,则返回相应的受保护的系统资源并允许访问者进行操作。而如果认证失败,则仍返回401状态,要求重新进行认证——有些浏览器只允许三次身份验证过程,如果三次身份验证都不成功,则显示出相关的错误信息而不再进行身份验证。但有些浏览器则一直停留在身份验证的界面中。9、Http基本验证方式请求响应的特点
(1)由于Http协议是无状态的,同一个客户端对同一个realm内的受保护的系统资源的每一次访问都会被要求进行身份认证。
(2)客户端浏览器通常会缓存用户名和密码,并和authentication realm一起保存。所以,一般不需要操作者重新输入用户名和密码——但其实内部是再次提交身份信息并进行身份验证的检查过程。
(3)由于用户的个人身份信息是以非加密的明文方式传输,虽然经过Base64的编码转换(因为Base64编码仅仅是编码,而不是加密)成了不易被人直接识别的字符串,但是仍然无法防止用户名密码被恶意盗用的安全风险。
10、Http基本验证方式的应用场合
在Http基本验证方式的通讯过程中,如果能够保证信息的数据包在中间环节的传输中不会被“截取”和“篡改”,例如Web应用系统是处于内部局域网或者底层协议是安全的(如使用SSL或其它一些安全机制,为验证过程提供数据加密、服务器端认证、信息真实性等方面的安全保证),完全可以弥补Http 基本验证方式在安全性方面的不足。
因此,Http基本验证方式可以广泛地应用在企业内部的各种管理系统中,如后台系统管理员的身份验证。
1.2在Tomcat中实现自定义表单身份验证
1.2.1基于自定义表单的验证技术及应用
1、基于自定义表单的身份验证
(1)基于From(自定义表单)的安全认证可以通过Tomcat 服务器对由开发人员所提供的Web 表单中所提供的身份验证的请求数据进行验证,基于自定义表单的身份验证可以使系统开发者自定义用户登录的页面和错误信息显示页面。
这也是与前面的基本身份验证方式的最大差别,其它的处理过程都基本相同,从而可以改善用户身份验证的视图界面,避免采用“千篇一律”的登录表单。如下示图为在某个Web应用系统中采用开发人员所提供的登录表单替换为由浏览器所弹出的“标准对话框”形式的登录表单。
(2)基于自定义表单的身份验证和基本身份验证之间的差别
这种验证方法与基本HTTP的验证方法差别不仅体现在登录表单可以自定义,也还体现在可以根据开发人员的要求制定登陆出错的目标页面。如下示图为在某个Web应用系统中采用开发人员所提供的登录失败时弹出错误信息提示页面,并在页面中显示出相关的错误信息——使得访问者能够明确为什么身份验证没有通过,而避免一直在登录中。
2、基于自定义表单的身份验证的实现原理
(1)J2EE Web容器通过拦截并检查用户的访问请求
检查正在访问的用户身份是否已在Web应用系统中已经创建好login session(登录会话)中保存。
(2)如果没有,则将用户的请求转向到身份认证服务的登录页面——该页面由开发人员在web.xml配置文件中配置定义,Web容器动态加载该页面从而使得用户进行身份登录验证。
(3)最后将用户的登录提交的请求数据传送给J2EEWeb容器
3、基于自定义表单的身份验证也仍然存在安全隐患
在J2EE Web容器的基于自定义表单的身份验证的规范中,并没有提供对用户所提交的身份信息进行加密转换保护的要求,浏览器仍然是以纯文本明文的方式发送到J2EE Web容器。因此,信息很容易被拦截和监听——存在一定的安全隐患。
4、在Tomcat中实现基于自定义表单的安全验证的过程
(1)首先定义用户和角色
在Tomcat中,用户、用户组和角色都是在XML配置文件(C:\jakarta-tomcat-5.0.19\conf\tomcat-users.xml)中指定的。
(2)设计登录页面表单
对该登录页面的表单有一定的要求——只需要提供一个登陆页面,包含一个名为j_security_check 的Form表单,一个名为j_username的TextBox(文本输入框)和一个名为j_password的PasswordBox (密码输入框)。示例