关于本教程
本教程是关于什么的?
也许没有比应用程序安全更重要的软件工程主题。 攻击是昂贵的,无论是来自内部还是外部,而且某些攻击可能会使软件公司承担赔偿责任。 随着计算机(尤其是Internet)技术的发展,安全攻击变得越来越复杂和频繁。 掌握最新技术和工具是应用程序安全的关键之一。 另一个是成熟的技术的坚实基础,例如数据加密,身份验证和授权。
在这个分为两部分的教程中,我们已经学习了Java平台的安全性功能。 第1部分是Java密码学的初学者介绍。 在这里,在第2部分中,我们将扩展讨论以涵盖访问控制,访问控制由Java身份验证和授权服务(JAAS)在Java平台中进行管理。
我应该学习本教程吗?
这是一个中级教程。 假定您知道如何读写基本的Java应用程序和applet。 如果您已经是Java程序员,并且对认证和授权技术以及支持它们的Java库感到好奇,那么本教程适合您。
我们将首先介绍身份验证和授权的基本概念,以及JAAS的体系结构概述。 接下来,我们将使用JAAS示例应用程序,通过分解应用程序的组件并查看最终执行结果,从理论到实践全面理解JAAS。 作为本练习的一部分,我们将研究各种JAAS配置选项,这些选项将有助于进一步巩固您所学的概念。
JAAS是一项复杂的技术,具有丰富的功能和特性。 我们将以一口大小的小块慢慢地介绍它,建议您不止一次地研究每个新概念。 到本教程结束时,您将拥有一个单独使用JAAS的良好基础。
您无需阅读本教程的第1部分即可了解第2部分。
工具,代码示例和安装要求
JAAS最初是对Java 2平台标准版的扩展。 但是,最近它已添加到1.4版中。 要完成本教程,您将需要以下内容:
- JDK 1.4,标准版
- 本教程的源代码和类JavaSecurity2-source.jar ,以便您可以按照示例进行操作。
- 支持Java 1.4插件的浏览器。
您可以使用JDK 1.3.x,但是必须自己安装JCE和JSSE。
概念概述
认证与授权
认证是人类用户或计算设备验证其身份的过程。 授权是一个过程,敏感软件通过该过程可以进行访问和依赖请求用户身份的操作。 这两个概念是齐头并进的。 未经授权,几乎不需要知道用户的身份。 如果没有身份验证,就无法区分受信任的用户和不受信任的用户,这使得无法安全地授权访问系统的许多部分。
识别或认证单个实体并不总是必要的; 在某些情况下,您可以按组进行身份验证,对给定组内的所有实体授予一定的授权。 在其他情况下,个人身份验证对于系统的安全至关重要。
身份验证和授权的另一个有趣方面是,单个实体在系统中可以具有多个角色。 例如,人类用户既可以是公司的雇员(这意味着他将需要访问公司电子邮件),又可以是公司内的一名会计师,这意味着他将需要访问公司会计系统。
认证要素
身份验证基于以下一个或多个元素:
- 你知道什么。 此类别包括其他人通常不知道的个人知道的信息。 示例包括PIN,密码和个人信息,例如母亲的娘家姓。
- 你有什么。 此类别包括使个人可以访问资源的物理项目。 示例包括ATM卡,安全ID令牌和信用卡。
- 你是谁。 此类别包括生物识别技术,例如指纹,视网膜轮廓和面部照片。
通常,仅使用一个类别进行授权是不够的。 例如,通常将ATM卡与PIN结合使用。 即使物理卡丢失,用户和系统也是安全的,因为小偷必须知道PIN才能访问任何资源。
授权要素
有两种控制对敏感代码的访问的基本方法:
- 声明性授权可以由系统管理员执行,该系统管理员配置系统的访问权限(即声明谁可以访问系统中的哪些应用程序)。 使用声明性授权,可以在不影响基础应用程序代码的情况下添加,更改或撤消用户访问特权。
- 程序授权使用Java应用程序代码来做出授权决策。 当授权决策需要更复杂的逻辑和决策时,程序授权是必需的,这超出了声明性授权的范围。 由于程序授权内置于应用程序代码中,因此要进行程序授权更改,就需要重写部分应用程序代码。
在本教程中,您将了解声明式和程序性授权技术。
保护用户和代码彼此
Java平台允许根据用户对代码的信任程度对计算资源(例如磁盘文件和网络连接)进行细粒度的访问控制。 Java平台的大多数基本安全功能旨在保护用户免受潜在恶意代码的侵害。 例如,由第三方证书支持的数字签名代码可确保代码源的身份。 根据他对代码源的了解,用户可以选择授予或拒绝对此代码的执行权限。 同样,用户可以基于给定代码源的下载URL授予或拒绝访问。
基于Java的系统上的访问控制是通过策略文件实现的,该策略文件包含以下语句:
grant signedBy "Brad", codeBase "http://www.bradrubin.com" {
permission java.io.FilePermission "/tmp/abc", "read";
};
该语句允许由“ Brad”签名并从http://www.bradrubin.com加载的代码读取/ tmp / abc目录。
其他Java平台功能(例如缺少指针)进一步保护了用户免受潜在恶意代码的侵害。 JAAS的认证和授权服务一起工作,提供了一项补充功能:它们保护敏感的Java应用程序代码免受潜在的恶意用户的攻击。
可插拔认证模块
JAAS实现了Java版本的可插入身份验证模块(PAM)框架。 Sun Microsystems为其Solaris操作系统创建了PAM。 通过JAAS,PAM现在可以独立于平台使用。
PAM的主要目的是允许应用程序开发人员在开发时写入标准身份验证接口,而由系统管理员决定使用哪种身份验证技术(以及如何使用它们)。 身份验证技术是在登录模块中实现的,登录模块可以在编写应用程序之后进行部署,并在称为登录配置文件的文本文件中指定(在本教程中名为login.config)。 login.config文件不仅可以指定要调用的模块,还可以指定总体身份验证成功的条件。
PAM允许将新的身份验证技术或技术更轻松地添加到现有应用程序中。 同样,可以通过更新login.config文件而不是重写整个应用程序来更改身份验证策略。
JDK 1.4随附以下PAM模块。 我们将在其中使用其中之一,并在本教程的后面部分练习编写我们自己的两个:
-
com.sun.security.auth.module.NTLoginModule
-
com.sun.security.auth.module.NTSystem
-
com.sun.security.auth.module.JndiLoginModule
-
com.sun.security.auth.module.KeyStoreLoginModule
-
com.sun.security.auth.module.Krb5LoginModule
-
com.sun.security.auth.module.SolarisSystem
-
com.sun.security.auth.module.UnixLoginModule
-
com.sun.security.auth.module.UnixSystem
JAAS示例和图表
在本教程中,我们将逐段查看JAAS示例应用程序的代码。 为了帮助跟踪全局,下图显示了所有这些部分如何组合在一起。 正在运行的示例(主程序JAASExample)首先使用两种技术或登录模块对用户进行身份验证,然后根据身份验证步骤的结果允许或禁止(或授权)访问两段敏感代码。
这是JAASExample程序的图。 下一个面板描述了操作流程。
![JAAS示例程序](https://i-blog.csdnimg.cn/blog_migrate/1883c20146159ec47e58d89bf2a2cfe7.png)
JAAS操作流程示例
以下是JAASExample图所示的总体认证和授权流程的简要说明。 在本教程的其余部分中,将更详细地描述以下每个步骤。
我们从身份验证的第一步开始,这是创建登录上下文并尝试登录LoginContext
是一个Java类,它使用login.config文件中的信息来确定要调用的登录模块以及将使用哪些条件。确定成功。 对于此示例,有两个登录模块。 第一个称为AlwaysLoginModule
,不需要密码,因此它总是成功的(这是不现实的,但是足以说明JAAS的工作原理)。 这个模块用关键字required
标记,这意味着它是成功所必需的(它总是如此)。 第二个模块称为PasswordLoginModule
,它需要一个密码,但是此模块的成功是可选的,因为它被标记为关键字optional
。 这意味着即使PasswordLoginModule
失败,总体登录仍然可以成功。
初始化之后,所选的登录模块将经历由LoginContext
控制的两阶段提交过程。 在此过程中,将调用UsernamePasswordCallbackHandler
以从由Subject
对象表示的个人获取用户名和密码。 如果认证成功,一个Principal
被添加到Subject
。 Subject
可能具有多个Principal
(在本例中为“ Brad”和“ joeuser”),每个Principal
都授权用户对系统进行不同级别的访问。 这样就完成了身份验证步骤。
身份验证完成后,我们将使用编程授权技术和doAs
方法,使用“ Subject
尝试执行一些敏感的工资单操作代码。 JAAS将检查Subject
是否被授权访问。 如果Subject
具有授权访问薪资代码的Principal
,则可以继续执行。 否则,将拒绝执行。
接下来,我们尝试使用声明性授权技术和doAsPrivilaged
方法执行一些敏感的人员操作代码。 这次,JAAS部署了用户定义的权限( PersonnelPermission
),Java策略文件(jaas.policy)和Java访问控制器( AccessController
)来确定执行是否可以继续。
JAAS中的认证
总览
在本节中,我们将重点介绍JAAS中的身份验证元素。 我们将从简单的登录和认证过程的描述开始,它将为您提供JAAS认证体系结构的高级视图。 接下来,我们将详细讨论架构的每个部分。 在本节的最后,您将有机会详细研究两个登录模块的代码。
如果您尚未这样做,那么现在该下载本教程的源代码JavaSecurity2-source.jar了 。 资料来源将更好地说明以下讨论中概述的步骤。
学科与校长
Subject
是表示单个实体(例如单个实体)的Java对象。 单个Subject
可以具有多个关联的标识,每个由Principal
对象表示。 因此,假设一个Subject
代表需要同时访问电子邮件系统和会计系统的员工。 该Subject
将具有两个Principal
,一个与员工的电子邮件访问用户ID关联,另一个与他的会计系统用户ID关联。
Principal
s为不是持久的,所以他们必须被添加到Subject
每一种在用户登录时Principal
被添加到Subject
作为一个成功的认证过程的一部分。 同样,如果身份验证失败,则从Principal
中删除Subject
。 无论身份验证是成功还是失败,当应用程序执行注销时,所有Principal
被删除。
除了包含一组Principal
, Subject
还可以包含两组凭据:一组公共凭据和一组私有凭据。 凭证是密码,密钥,令牌等。 对公共和私有证书集的访问由Java权限控制,我们将在本教程的后面部分讨论。 有关凭据的完整讨论超出了本教程的范围。
受试者的方法
Subject
对象具有几种方法,其中一些方法如下:
-
subject.getPrincipals()
返回一组Principal
对象。 因为结果是Set
,所以remove()
,add()
和contains()
。 -
subject.getPublicCredentials()
返回与Subject
关联的一组公共可访问凭据。 -
subject.getPrivateCredentials()
返回与Subject
关联的一组私有可访问凭据。
主体接口
Principal
是Java接口。 程序员编写的PrincipalImpl
对象实现Principal
接口以及Serializable
接口,名称字符串,返回该字符串的getName()
方法以及其他支持方法,例如hashCode()
, toString()
和equals()
。
在登录过程中将Principal
添加到Subject
。 正如我们将在后面看到的那样,声明性授权基于策略文件中的条目。 提出授权请求后,系统的授权策略将与Subject
包含的Principal
进行比较。 如果Subject
的Principal
符合策略文件中的安全性要求,则授予授权; 否则将被拒绝。