第八讲 J2EE安全机制
本讲内容 8.1 Java安全模型 8.2 基本Java安全体系结构 8.3 扩展Java安全体系结构 8.4 J2EE安全策略
概述 自从Java设计之初,安全便成为Java编程语言、运行系统、API与工具集的主要考虑。 JDK 1.0开始引入了“砂箱”(Sandbox)方法,用于保护移动代码。 JDK 1.1开始提供对签名Applet、消息摘要、数字签名和数字证书的支持。 JDK 1.2(即Java 2)增加了可配置安全策略、证书管理等功能。
Java 2 Security包、JCE、JSSE和JAAS一起提供了开发安全的、基于Web的、分布式应用程序的综合框架。 概述(续) Java 2的几种面向安全的扩展内容 JCE(Java Cryptography Extension,Java加密扩展),提供了加密、密钥生成、密钥协议与验证算法等功能。 JSSE(Java Secure Socket Extension,Java安全套接字扩展),用于增加对基于SSL的HTTP协议的支持。 JAAS(Java Authentication and Authorization Service,Java验证与授权服务),主要用于控制哪些用户能够运行哪些特定的操作。 Java 2 Security包、JCE、JSSE和JAAS一起提供了开发安全的、基于Web的、分布式应用程序的综合框架。
安全模型的关键概念,允许通过改变砂箱的参数来实现对程序运行权限的控制。 8.1 Java安全模型 安全模型的关键概念,允许通过改变砂箱的参数来实现对程序运行权限的控制。 8.1.1 砂箱 权限 规定了代码允许执行的具体操作,主要通过权限类型、权限名和 操作类型决定。 代码源 指定类所在的URL地址,包括代码基和签名者。 保护域 将代码源和权限组合使用。 策略文件 包括一个或多个保护域定义的文本文件,完成权限所指定的任 务,是将砂箱的其他各个要素结合起来。 密钥库 即保存证书的位置。
8.1 Java安全模型(续) 8.1.2 JDK1.0 安全模型 安全控制是通过砂箱控制实现的,所有远程下载的代码都在砂箱中运行。 代码 操作系统资源 Java虚拟机
8.1 Java安全模型(续) 8.1.3 JDK1.1 安全模型 JDK 1.0安全模型中所有的远程代码都无法直接访问本地操作系统资源,这使得基于Web的应用程序难以下载执行。 JDK 1.1中引入了信任安全模型,可以指定哪些提供签名的代码能够访问本地系统资源。
8.1 Java安全模型(续) 8.1.3 JDK1.1 安全模型(续) 非信任远程 Java代码 本地Java 代码 砂箱 操作系统资源
8.1 Java安全模型(续) 8.1.4 JDK1.2 安全模型 JDK 1.2版本以后,可配置的安全策略模型,无论是本地代码或者是下载到本地的远程代码,都遵循一个可配置的安全策略。 远程Java 代码 本地Java 砂箱 操作系统资源 Java虚拟机 可配置安全 策略
8.2 基本Java 2 安全体系结构 基本Java安全体系结构图 理论上存取控制器可完全取代安全管理器了,但为了保证JDK 1.2以前程序不至于全部失效,而是对安全管理器作了必要的补充。 各类Java应用 操作系统、程序专用资源 类装载器 JRE Java平台类 字节码验证器 安全管理器 存取控制器 权限、 策略、 保护域 Java 2 平台
具体实施表现在Java程序编译、将类装载入虚拟机以及运行阶段。 必须严格遵守实体访问级别的操作要求(Private,Protected,Public) 。 程序不能访问任意的内存地址(final) 。 变量在初始化之前不能使用(本地变量,实例变量) 。 对于所有的数组访问都必须进行越界检查(安全漏洞) 。 对象不能任意强制转换为其他类型对象(除超类或子类类型) 。 具体实施表现在Java程序编译、将类装载入虚拟机以及运行阶段。
但数组越界检查和对象类型转换检查需在运行时进行。 8.2 基本Java 2 安全体系结构(续) 字节码验证器 属于Java虚拟机的一部分,没有任何接口,程序员无法直接访问,用户也不能与之进行交互。 证明从Java 2平台之外装载的Java应用程序字节码满足: 类文件格式的正确性。 不会基于final类派生出子类,不会覆盖final方法。 每个类(除了Object类以外)都有一个超类。 不存在类型之间的非法转换。 操作数栈不存在溢出。 但数组越界检查和对象类型转换检查需在运行时进行。
8.2 基本Java 2 安全体系结构(续) 类装载器 是Java虚拟机的关键组件之一,主要负责将Java类字节码读入Java虚拟机,并转换成类定义的形式。 可以结合虚拟机定义命名空间,保护Java语言本身的安全特性。 在必要的时候将调用安全管理器,从而保证代码在定义或访问相关类时具有适当的权限。 建立了权限与类对象之间的映射,这样存取控制器就可以知道哪些类拥有哪些权限了。
8.2 基本Java 2 安全体系结构(续) 类装载器的结构 系统类装载器 URL类装载器 http://www.abc.com http://www.cde.com 其他URL类装载器 … 系统类装载器 URL类装载器 http://www.abc.com http://www.cde.com 其他URL类装载器 …
8.2 基本Java 2 安全体系结构(续) 安全管理器 从Java API的角度来看,应用的安全策略是由安全管理器负责的,通过安全管理器才能确定与安全相关的某项操作是否能够执行。 Java.lang.SecurityManager类为其他Java API提供了相应的接口,其checkPermission方法又会调用java.security.AccessController类,用来存取控制器中的内容,检查某项操作是否可以执行。
8.2 基本Java 2 安全体系结构(续) 存取控制器 可为用户主机上的大部分关键资源提供保护,而且允许用户为具体的应用指定安全策略,只需要修改java.policy等类似的策略文件中的授权项即可。 通过创建权限类使得存取控制器可以利用权限类对象,按具体要求决定是否可以访问某个资源(扩展) 。 权限、策略是建立存取控制器的基础。
8.2 基本Java 2 安全体系结构(续) Java 安全包(java.security package) 与其他安全相关类一起被置于JDK核心类中。
8.3 扩展Java 2 安全体系结构 扩展Java 2 安全体系结构图 基于基本Java 2 安全体系结构和JCA 。 Java加密扩展 (JCE) Java安全套接字 扩展(JSSE) Java验证与授权 服务(JAAS) 基本Java2安全 体系结构 Java加密体系 结构(JCA) Java 2 平台 Java加密扩展 (JCE) Java安全套接字 扩展(JSSE) Java验证与授权 服务(JAAS) 基本Java2安全 体系结构 Java加密体系 结构(JCA) Java 2 平台
8.3 扩展Java 2 安全体系结构(续) 扩展Java 2 安全体系结构中的组件: 字节码验证器 类装载器 安全管理器 存取控制器 JCE JSSE JAAS
8.3 扩展Java 2 安全体系结构(续) JCA(Java Cryptography Architecture,Java加密体系结构) JCA提供了Java平台实现基本加密功能的工具,包括JDK 1.2安全API中与密码有关的部分,以及一组相关约定和规范。
8.3 扩展Java 2 安全体系结构(续) Java密码扩展(JCE) 虽然JCA也是java.security包的一部分,但是其基 Java密码扩展(JCE)是对JCA API的扩展,包括用 于加密、密钥交换和信息认证码(MAC)的API, 支持对称加密、非对称加密、流式密码处理等, 同时还支持序列化加密对象。 JCE和JDK密码共同提供了一个与平台无关的完 整密码API 。
8.3 扩展Java 2 安全体系结构(续) Java安全套接字扩展(JSSE) 是Java基本安全平台的扩充,提供了SSL和TLS协议的Java实现,并提供了数据加密、服务器验证、消息完整性、客户端认证等功能,增强了网络通信的安全性。 利用JSSE,开发者可以在服务器和客户端之间建立安全的数据通信,而不用考虑采用哪种通信协议(HTTPS、Telnet、FTP) 。
8.3 扩展Java 2 安全体系结构(续) Java安全套接字扩展(续) 通过抽象复杂的安全算法和“握手”机制,JSSE使得遭受危险性攻击的可能性降到了最低。 JSSE采用构件的形式可以直接集成到应用程序中,使得应用程序的开发变得非常简单。
8.3 扩展Java 2 安全体系结构(续) Java验证与授权服务(JAAS) 提供了一个框架,开发人员可以根据此框架要求执行相关代码的用户必须拥有相应的权限。 首先,JAAS提供了一组用于实现用户鉴别的类(要求用户登录)。此外,JAAS还提供了另一组类,其作用是授权用户执行某些特定的操作。
8.3 扩展Java 2 安全体系结构(续) Java验证与授权服务 (续) JAAS提供了针对代码的运行进行控制这一机制,增强了Java的安全性,而传统Java代码的安全只是基于代码源以及代码签名者。 JAAS还采用“可插拔”的运行方式,因此,在升级或新增验证技术时,并不需要对应用程序作任何修改。
8.3 扩展Java 2 安全体系结构(续) Java验证与授权服务 (续) 对于开发人员,使用JAAS包括两步: 首先发出调用以鉴别用户; 然后代表用户执行相应的方法。 对于系统管理员,需要三步: 首先配置鉴别用户时需要调用的模块; 然后配置一组JAAS策略文件; 最后建立正确的程序执行环境。
8.4.1 J2EE安全概述 J2EE安全模型,能够配置Web组件或企业Bean,以保证系统资源只能被授权的用户所访问,这样每一客户属于一个特别的角色,而每个角色只允许激活特定的方法。
8.4.1 J2EE安全概述(续) JAVA安全认证框架(JAF),提供一些安全控制方面的框架,让开发者通过各种部署和自定义实现自己的个性安全控制策略。
8.4.1 J2EE安全概述(续) J2EE应用程序设计模型使开发人员不需要了解应用程序安全性机制特有的实现细节,J2EE平台在某种程度上具备这种隔离性,从而增强了应用程序的可移植性,允许在不同的安全环境中部署应用程序。
8.4.1 J2EE安全概述(续) J2EE安全体系的目的是在实现各层安全的基础上实现各层相关联的应用程序整体安全。
8.4.2 安全方法 J2EE和Web服务应用程序由可在不同容器中部署的组件构成,组件的安全性由它们的容器提供: 声明性安全 程序性安全
8.4.2.1 声明性安全 声明性安全表示应用程序的安全结构,包括安全角色、访问控制和身份验证要求等,且在应用程序的外部(在部署描述符中) 。 在应用程序的安全上下文中,应用程序提供者要提供能完全满足应用程序配置要求的声明机制。 应用程序部署者使用各种J2EE服务器的不同工具将部署描述符描述的应用程序安全需求映射到J2EE容器实现的安全机制。
8.4.2.2 程序性安全 程序性安全是指用安全敏感的程序来实现安全控制,它隐藏在应用程序中,用来做安全判决。 当单独的声明性安全不足以表示应用程序的安全模型时,程序性安全就很有用。
8.4.3.1 受保护资源 受保护资源只有授权用户可以访问,授权基于识别和身份验证,提供对受保护资源的控制访问。 识别是能够“认出”系统实体的过程。 身份验证是校验计算机系统中的用户、设备或者其他实体身份的过程,通常作为允许访问系统资源的必要条件。
8.4.3.2 不受保护资源 访问不受保护资源的实体不需要授权。 访问不受保护资源的实体也不需要身份验证。 访问系统资源而未经授权的行为被称作未授权访问或者匿名访问。
8.4.4 用户、组、域和角色 J2EE用户指个体(或者应用程序)身份,可将用户和组联系在一起。 域是指由相同身份验证策略管理的一批用户和组,亦即被相同的安全验证规则所约束的用户集合。 角色指由应用程序组装者定义的访问具体资源组的权限的一个抽象的名字,即抽象的逻辑用户分组。
8.4.4 用户、组、域和角色(续) 一个J2EE组也代表一个用户分类,但是和角色有不同的范围。 J2EE组被指定到整个J2EE服务器,而角色只覆盖一个特定的应用程序。
8.4.4 用户、组、域和角色(续) 在开发J2EE应用程序时,不需要知道已经为应用程序将要在其中运行的域定义的用户类型。
8.4.4 用户、组、域和角色(续) 在部署应用程序时,部署者将角色映射到运行环境中的安全实体。 创建用户 和/或组 在应用程序中定义角色 映射角色到 用户或组 用户 1 2 3 组1 a b c 应用程序 角色1 角色2 创建用户 和/或组 在应用程序中定义角色 映射角色到 用户或组 用户 1 2 3 组1 a b c 应用程序 角色1 角色2 创建用户 和/或组 在应用程序中定义角色 映射角色到 用户或组 用户 1 2 3 组1 a b c 应用程序 角色1 角色2 一个有特定角色的用户就有了相应的J2EE应用程序访问权。
8.4.4 用户、组、域和角色(续) J2EE验证服务在两个域中管理用户: 证书通常在HTTPS协议中被用来验证Web浏览器客户端。 缺省域 证书通常在HTTPS协议中被用来验证Web浏览器客户端。 缺省域用来验证除Web浏览器客户端之外的所有用户。 一个缺省域的J2EE用户可以属于J2EE组,证书域的用户不能属于J2EE组。
8.4.5 Web层安全 Web容器激活为受保护的Web资源配置的身份验证机制: HTTP基本验证(用户名和密码) 。 基于FORM的验证(自定义登录页面和错误提示页) 。 客户端证书验证。 相互身份验证。 摘要身份验证(通过加密形式传送密码) 。
8.4.5 Web层安全(续) HTTP基本身份验证 将用户名和密码作为uu编码,并不特别安全。 客户端 服务器 1.请求受保护的资源 2.请求用户名:密码 3.发送用户名:密码 4.返回被请求的资源 客户端 服务器 1.请求受保护的资源 2.请求用户名:密码 3.发送用户名:密码 4.返回被请求的资源 将用户名和密码作为uu编码,并不特别安全。 HTTP基本身份验证
8.4.5 Web层安全(续) 基于表单的身份验证 用户对话框的内容作为纯文本发送,也不特别安全。 服务器 客户端 j_security_check ? login.jsp error.jsp 1.请求受保护的资源 3.来自提交 4.改向到资源 2.改向到登录页面 返回的错误页面 失败 成功 用户对话框的内容作为纯文本发送,也不特别安全。 基于表单的身份验证
8.4.5 Web层安全(续) 基于证书的相互身份验证 客户端 服务器 信任库 server.keystore server.cert 4.发送用户名:密码 5.访问受保护的资源 3.验证证书 1.请求受保护的资源 2.出示证书 基于证书的相互身份验证
8.4.5 Web层安全(续) 基于用户名和密码的相互身份验证 server.keystore 客户端 服务器 信任库 server.cert 4.出示证书 6.访问受保护的资源 3.验证证书 1.请求受保护的资源 2.出示证书 client.keystore client.cert 5.验证证书 基于用户名和密码的相互身份验证
8.4.5 Web层安全(续) 不管是基本验证还是基于Form的验证都无法保证密码的机密性,都不能确保安全。 客户端证书验证是比上两种方法更安全的身份验证方法,它使用基于SSL的HTTP,服务器和客户端(可选)使用公钥证书相互验证身份。
8.4.5 Web层安全(续) Web层程序性安全由HttpServletRequest接口的下述方法组成: getRemoteUser isUserInRole getUserPrincipal
8.4.6 EJB层安全 声明方法权限(表明哪些角色被准许调用哪些方法) 。 映射角色到J2EE用户和组。
8.4.6 EJB层安全(续) EJB层受保护资源包括被应用程序客户端调用的企业Bean方法、Web组件或者其他企业Bean 。 getCallerPrincipal(确定企业Bean的调用者) isCallerInRole(确定调用者是否具有指定的角色)
8.4.7 应用程序客户端层安全 Java验证和授权服务(Java Authentication and Authorization Service ,JAAS)机制扩展了Java2平台的安全架构,提供了一种基于用户的授权方式,是标准嵌入式验证模块(PAM)框架的Java版实现。
8.4.7 应用程序客户端层安全(续) 可以将JAAS用于身份验证,JAAS允许应用程序保持独立的基本身份验证技术,让J2EE应用程序去验证并授权某个特定用户或用户组来执行它。 可以在应用程序内插入新的或者改进的身份验证技术,而不用修改应用程序本身。 使应用程序独立于底层的安全技术实现。
8.4.8 EIS层安全 EIS可能需要请求者的签名以访问资源
8.4.8 EIS层安全(续) 配置资源适配器的安全性: 身份验证机制 重新验证支持 安全权限
8.4.9 可传递的安全身份 传播安全身份的方式 目的容器无法验证传播的安全标识,但必须信任调用容器传播验证过的安全标识。 将中间组件的调用者安全身份传递给目的企业bean(被调用者),当目的容器信任中间组件时。 将特定的安全身份传递给目的企业bean,当目的容器期望通过特定的安全身份访问时。 目的容器无法验证传播的安全标识,但必须信任调用容器传播验证过的安全标识。
8.4.9 可传递的安全身份(续) 安全标识的传播 启动客户端 中间组件 目标 应用程序客户端 或Web客户端 EJB或Web容器 J2EE安全标识 被传播的安全 标识(J2EE) 安全标识的传播
小结 客户端验证仅仅是一方面。 另一方面,服务器端验证是构建安全Web应用程序必需的,只有服务器端验证才可以提供真正应用程序级的安全。
小结(续) J2EE Web应用程序的安全性并非仅仅是在web.xml 和ejb-jar.xml文件中使用合适的声明,也不仅仅是使用J2EE技术,如JAAS,而是经过深思熟虑后的设计,且实现一个支持它的架构。
作业和思考题 请给出扩展Java 2安全体系结构图及其简要说明。 试列举J2EE中Web层安全的主要身份验证机制。
下课了。。。 休息一会儿。。。