JAAS:灵活的Java安全机制(3)

转载 2004年07月18日 21:14:00
 配置文件

  上面我已经提到,JAAS的可扩展性来源于它能够进行动态配置,而配置信息通常是保存在文本。这些文本文件有很多个配置块构成,我们通常把这些配置块称作申请(Application)。每个申请对应了一个或多个特定的LoginModule对象。

  当你的代码构造一个LoginContext对象时,你需要把配置文件中申请的名称传递给它。LoginContext将会根据申请中的信息决定激活哪些LoginModule对象,按照什么顺序激活以及使用什么规则激活。

  配置文件的结构如下所示:

Application {
ModuleClass Flag ModuleOptions;
ModuleClass Flag ModuleOptions;
...
};
Application {
ModuleClass Flag ModuleOptions;
...
};
...

  下面是一个名称为Sample的申请

Sample {
com.sun.security.auth.module.NTLoginModule Rquired debug=true;
}

  上面这个简单的申请指定了LoginContext对象应该使用NTLoginModule进行验证。类的名称在ModuleClass中被指定。Flag控制当申请中包含了多个LoginModule时进行登录时的行为:Required、Sufficient、Requisite和Optional。最常用的是Required,使用它意味着对应的LoginModule对象必须被调用,并且必须需要通过所有的验证。由于Flag本身的复杂性,本文在这里不作深究。

  ModuleOption允许有多个参数。例如你可以设定调试参数为True(debug=true),这样诊断输出将被送到System.out中。

  配置文件可以被任意命名,并且可以被放在任何位置。JAAS框架通过使用java.securty.auth.long.config属性来确定配置文件的位置。例如当你的应用程序是JaasTest,配置文件是当前目录下的jaas.config,你需要在命令行中输入:

java -Djava.security.auth.login.config=jass.config JavaTest

  图二描述了配置文件中各元素之间的关系

jt-2003-1-14-image002.gif
图二 JAAS的配置文件

  通过命令行方式进行登录验证

  为了说明JAAS到底能干什么,我在这里编写了两个例子。一个是简单的由命令行输入调用的程序,另一个是服务器端的JSP程序。这两个程序都通过用户名/密码的方式进行登录,然后使用关系数据库对其进行验证。

  为了通过数据库进行验证,我们需要:

  1. 实现RdbmsLoginModul类,该类可以对输入的信息进行验证。

  2. 编辑一个配置文件,告诉LoginContext如何使用RdbmsLoginModule。

  3. 实现ConsoleCallbackHandler类,通过该类可以获取用户的输入。

  4. 编写应用程序代码。

  在RdbmsLoginModul类中,我们必须实现LgoinModule接口中的五个方法。首先是initialize()方法:

public void initialize(Subject subject, CallbackHandler
callbackHandler,

Map sharedState, Map options)
{
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;

url = (String)options.get("url");
driverClass = (String)options.get("driver");
debug = "true".equalsIgnoreCase((String)options.get("debug"));
}

  LoginContext在调用login()方法时会调用initialize()方法。RdbmsLoginModule的第一个任务就是在类中保存输入参数的引用。在验证成功后将向Subject对象中送入Principal对象和凭证。

  CallbackHandler对象将会在login()方法中被使用到。sharedState可以使数据在不同的LoginModule对象之间共享,但是在这个例子中我们不会使用它。最后是名为options的Map对象。options向LgoinModule对象传递在配置文件ModuleOption域中定义的参数的值。配置文件如下所示:

Example {
RdbmsLoginModule required
driver="org.gjt.mm.mysql.Driver"
url="jdbc:mysql://localhost/jaasdb?user=root"
debug="true";
};

  在配置文件中,RdbmsLoginModule包含了五个参数,其中driver、url、user和password是必需的,而debug是可选阐述。driver、url、user和password参数告诉我们如何获得JDBC连接。当然你还可以在ModuleOption域中加入数据库中的表或列的信息。使用这些参数的目的是为了能够对数据库进行操作。在LoginModule类的initialize()方法中我们保存了每个参数的值。

  我们前面提到一个LoginContext对应的配置文件告诉它应该使用文件中的哪一个申请。这个信息是通过LgoinContext的构造函数传递的。下面是初始化客户端的代码,在代码中创建了一个LoginContex对象并调用了login()方法。

ConsoleCallbackHandler cbh = new ConsoleCallbackHandler();
LoginContext lc = new LoginContext("Example", cbh);
lc.login();

  当LgoinContext.login()方法被调用时,它调用所有加载了的LoginModule对象的login()方法。在我们的这个例子中是RdbmsLoginModule中的login()方法。

  RdbmsLoginModule中的login()方法进行了下面的操作:

  1. 创建两个Callback对象。这些对象从用户输入中获取用户名/密码。程序中使用了JAAS中的两个Callback类:NameCallback和PasswordCallback(这两个类包含在javax.security.auth.callback包中)。

  2. 通过将callbacks作为参数传递给CallbackHandler的handle()方法来激活Callback。

  3. 通过Callback对象获得用户名/密码。

  4. 在rdbmsValidate()方法中通过JDBC在数据库中验证获取的用户名/密码。

  下面是RdbmsLoginModule中的login()方法的代码

public boolean login() throws LoginException {
if (callbackHandler == null)
throw new LoginException("no handler");

NameCallback nameCb = new NameCallback("user: ");
PasswordCallback passCb = new PasswordCallback("password: ", true);
callbacks = new Callback[] { nameCb, passCb };
callbackHandler.handle(callbacks);

String username = nameCb.getName();
String password = new String(passCb.getPassword());
success = rdbmsValidate(username, password);

return(true);
}

  在ConsoleCallbackHandler类的handle()方法中你可以看到Callback对象是如何同用户进行交互的:

public void handle(Callback[] callbacks)
throws java.io.IOException, UnsupportedCallbackException {

for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
NameCallback nameCb = (NameCallback)callbacks[i];
System.out.print(nameCb.getPrompt());
String user=(new BufferedReader(new

InputStreamReader(System.in))).readLine();
nameCb.setName(user);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback passCb = (PasswordCallback)callbacks[i];
System.out.print(passCb.getPrompt());
String pass=(new BufferedReader(new

InputStreamReader(System.in))).readLine();
passCb.setPassword(pass.toCharArray());
} else {
throw(new UnsupportedCallbackException(callbacks[i],
"Callback class not supported"));
}
}
}

从Hadoop 安全机制原理到当今主流安全机制

在Hadoop Common模块中除了之前我所分析过的4大主模块,还有一个也同样是非常重要的内容,就是Security---安全模块。不过,我只是简单的分析他的实现机制,并不会涉及代码的分析。同时,我...
  • Androidlushangderen
  • Androidlushangderen
  • 2014年12月13日 09:10
  • 4074

JavaSecurity和JAAS——Java标准安全体系概述(下)

java标准安全体系分为两大部分,一个是在JDK1.0引入并在JDK2进行了重构的代表着以代码为中心的授权体系。此体系下,关注的重点在于“这段代码能访问哪些系统资源”;另一个是在JDK1.3以扩展的形...
  • m0_37962779
  • m0_37962779
  • 2017年11月01日 15:28
  • 130

ActiveMQ 基于JAAS的安全机制

ActiveMQ版本 :5.9 ActiveMQ支持可插拔的安全机制,用以在不同的provider之间切换。 JAAS认证插件 JAAS(Java Authentication and Au...
  • sunshine_love
  • sunshine_love
  • 2015年03月07日 19:42
  • 1960

java安全 ——JAAS(Java 认证和授权服务)开发指南

以下内容转自: http://lyb520320.iteye.com/blog/720478 【0】README 1)本文翻译自:http://java.sun.com/developer/tec...
  • PacosonSWJTU
  • PacosonSWJTU
  • 2016年02月21日 18:53
  • 1603

java语言安全机制浅析

java通过所谓的沙箱安全模型保证了其安全性,下面我们就来看看java提供的安全沙箱机制。 组成沙箱的基本组件如下: 1.类装载器结构; 2.class文件检验器; 3.内置于...
  • RowandJJ
  • RowandJJ
  • 2014年05月20日 11:55
  • 2862

Jaas原理及实现

JAAS是对JCE安全框架的重要补充,通过提供认证用户和确定用户授权来增强JAVA解决方案的动态安全性,使得资源能够得到很好得到保护和控制(JAAS使用动态的安全策略来定义权限,而不是将其静态的嵌入到...
  • Jesse621
  • Jesse621
  • 2015年01月30日 11:54
  • 2568

Java 多线程安全机制

什么是多线程安全,java中有哪些机制可以保证线程安全
  • JackieeeCheng
  • JackieeeCheng
  • 2017年04月08日 20:46
  • 1256

java线程安全和锁机制详解

java线程安全和锁机制详解 . 在开始这篇blog之前应该先了解几个概念: 临界区: 保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行...
  • beyond59241
  • beyond59241
  • 2016年03月14日 19:59
  • 2036

Java线程安全 - 线程(3)

1. 线程安全《Java Concurrency In Practice》的作者Brian Goetz对“线程安全”有一个比较恰当的定义: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环...
  • u010297957
  • u010297957
  • 2016年04月15日 18:09
  • 861

Java RMI之HelloWorld程序以及相关的安全管理器的知识

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方...
  • wjrong_1
  • wjrong_1
  • 2015年07月22日 16:38
  • 1468
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAAS:灵活的Java安全机制(3)
举报原因:
原因补充:

(最多只允许输入30个字)