标题：JAAS
JAAS简介
Java安全框架最初集中在保护用户运行潜在的不可信任代码，是基于代码的来源（URL）和谁创建的代码（certificate）来给移动代码进行授权。Java 2 SDK 1.3引入了JAAS（ Java Authentication and Authorization Service）,增加了基于用户的访问控制能力，即根据谁在运行代码来进行授权。JAAS已经整合进了Java 2 SDK 1.4，作为标准的用户认证与授权模型。
JAAS用户认证框架
JAAS认证被实现为可插入的方式，允许应用程序同底层的具体认证技术保持独立，新增或者更新认证方法并不需要更改应用程序本身。应用程序通过实例化LoginContext对象开始认证过程，引用配置文件中的具体认证方法，即LoginModule对象，来执行认证。
JAAS：可插入式认证
一旦执行代码的用户通过了认证，JAAS授权组件将和核心Java访问控制模型一起工作，来保护对敏感资源的访问。从J2SDK 1.4开始，访问控制不仅基于代码的来源和签名者（CodeSource），而且还要检查谁在运行代码。执行代码的用户被表现为Subject对象，如果LoginModule认证成功，Subject对象被更新为相应的Principals和credentials。25.1.1. 一个简单的例子
本节通过一个简单的例子介绍JAAS开发的基本步骤。本节中的范例位于Apusic应用服务器安装目录中的docs/samples/jaas/simple目录。有关范例的内容、编译、部署与运行，可参考docs/samples/jaas/simple目录下的readme.txt文件。
范例程序的代码分为两部分，一部分为主程序，执行用户认证过程，源程序如下：
package samples;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import com.sun.security.auth.callback.TextCallbackHandler;
public class CountFiles {
static LoginContext lc = null;
public static void main(String[] args) {
//使用配置文件中名字为“CountFiles”的条目
try {
lc = new LoginContext("CountFiles",
new TextCallbackHandler());
} catch (LoginException le) {
le.printStackTrace();
System.exit(-1);
} 
try {
lc.login();
//如果没有异常抛出，则表示认证成功
} catch (Exception e) {
System.out.println("Login failed: " + e);
System.exit(-1);
}
//以认证用户的身份执行代码
Object o = Subject.doAs(lc.getSubject(), new CountFilesAction());
System.out.println("User " + lc.getSubject( ) + " found " + o + " files.");
System.exit(0);
}
}
可以看出，主程序包含了三个重要的步骤：首先构造一个LoginContext对象，然后使用这个对象进行登录，最后，把用户作为doAs方法一个参数。
另一部分表示用户想要执行的具体操作，源程序如下：
package samples;
import java.io.File;
import java.security.PrivilegedAction;
class CountFilesAction implements PrivilegedAction {
public Object run() {
File f = new File(".");
File[] files = f.listFiles();
return new Integer(files.length);
}
}
25.1.2. JAAS核心类和接口JAAS相关的核心类和接口分为三类，公共、认证和授权。
公共类：Subject,，Principal，Credential
认证类和接口：LoginContext，LoginModule，CallbackHandler，Callback
授权类 ：Policy，AuthPermission，PrivateCredentialPermission
详细的描述请参考《JAAS Reference Guide》。
25.1.3. 配置LoginModules
JAAS认证被实现为一种可插入的方式，系统管理员可以通过配置文件为每一个应用程序配置LoginModuls来决定应用程序使用的认证技术。配置信息可以保存在文件或数据库中，通过javax.security.auth.login.Configuration对象进行读取。javax.security.auth.login.Configuration为抽象类，JDK提供了可实例化的子类com.sun.security.auth.login.ConfigFile，从文件中读取配置信息。配置文件中包含一个或多个条目，每一个条目指明了特定应用程序使用的认证方法。条目的结构如下：
<name used by application to refer to this entry> { 
<LoginModule> <flag> <LoginModule options>;
<optional additional LoginModules, flags and options>;
};
可以看出，每一个条目由名字和一个或多个LoginModule组成。范例程序使用的配置文件login.conf内容如下：
CountFiles {
com.apusic.security.auth.login.ClientPasswordLoginModule required;
};
详细的描述信息可以参考Configuration。25.1.4. 编写Policy文件JAAS授权扩展了现有的Java安全体系结构，在给代码授权时可以包括一个多个Principal域，指出Principal代表的用户执行特定的代码时，具有分配的权限。因此，授权声明的基本形式为：
grant <signer(s) field>, <codeBase URL> 
<Principal field(s)> {
permission perm_class_name "target_name", "action";
....
permission perm_class_name "target_name", "action";
};
缺省的策略文件实现和策略文件语法请参考《Default Policy Implementation and Policy File Syntax》。范例程序使用的策略文件policy.jaas内容如下：
grant codeBase "file:./build" {
permission java.security.AllPermission;
};
grant codeBase "file:/${apusic.home}/lib/apusic.jar" {
permission java.security.AllPermission;
};
grant codeBase "file:./build/actions" Principal com.apusic.security.PrincipalImpl "admin" {
permission java.io.FilePermission "<<ALL FILES>>", "read";
};
可以看出，给主程序和apusic.jar授予了所有权限；当执行具体操作的用户为“admin”时，授予了读取所有文件的权限。25.1.5. 运行范例程序范例程序提供了ant的build.xml脚本，请用户自己下载并安装ant。运行范例程序的步骤为：
首先启动Apusic应用服务器， 范例程序将登录服务器。
编译、运行程序。在simple目录下执行ant命令，会编译源程序CountFiles.java到build目录下，编译源程序CountFilesAction.java到build/actions目录下。然后会自动运行程序，相当于在命令行敲入下面的java命令：
java -classpath %APUSIC_HOME%/lib/apusic.jar;./build;./build/actions
-Djava.security.manager 
-Djava.security.policy==policy.jaas 
-Djava.security.auth.login.config==login.conf 
-Dapusic.home=%APUSIC_HOME% samples.CountFiles
根据提示输入服务器，用户名和口令。 如果用“admin”登录，程序将正常运行结束，若使用其他用户名登录，将抛出访问控制异常。