`
Callan
  • 浏览: 736032 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JAAS简介及实例

    博客分类:
  • Java
阅读更多

JAAS是对JCE安全框架的重要补充,通过提供认证用户和确定用户授权来增强JAVA解决方案的动态安全性,使得资源能够得到很好得到保护和控制(JAAS使用动态的安全策略来定义权限,而不是将其静态的嵌入到代码中)。

JAAS采用的是插件的运行方式,一开始就被设计成可插拔的(Pluggable),根据应用的需要,只要配置一下JAAS的配置文件,这些组件即可包含 在我们的应用程序中。使用JAAS包接口,开发者和第三方可以开发一些组件或者BEAN来实现登陆认证,或者通过与使用者或外部的系统的进行交互来访问认 证信息(当然我们可以设计更为稳妥安全的密码学协议)。JAAS提供了一组用于用户鉴别的类和接口,这意味着支持JAAS的应用会要求用户登陆,同时 JAAS提供了另一组用于用户授权的类和接口。在讨论例子之前,先对JAAS API中常用的一些类和接口做个简单的说明。

LoginModule :确认用户的合法性(使用CallbackHandler或者其他类方法),并分配访问权限principal给subject;

LoginContext:为了实现用户鉴别,建立相应的环境,从配置文件中导入规则;

CallbackHandler:回调处理器,负责与用户(代码拥有者和执行者)交互,确认其身份的合法性;

Subject:表示登陆处理的目标,即一个被鉴别的用户。并可关联一个或多个pirncipal;

Principal:表示具有访问权限的一个实体,可以看作是可以执行某种操作的证件。

理解这些类和接口的关系我给个生动的比方:一个军事学校,入学的时候校方(LoginModule)根据学生(Subject)的入学通知来确定其合法 性,这个过程交由某工作人员(CallbackHandler)执行,(CallbackHandler)确认后,(LoginModule)给不同 (Subject)根据其身份发给相关的证件(Principal),有了该证件就可以访问对应的资源,(Subject)根据自己的 (Principal)的级别可以使用和访问学校不同资源。

一个(Subject)的(Principal)如果是士官级,那么可以访问的资源就相对少些,如果是将军级那就多些。当然一个(Subject)可以拥有多个(Principal)。

通过分析我们会发现,JAAS采用的也是身份检查+权限分配模式。因此JAAS的应用也分成两个部分:(1)认证;(2)授权。过程是先认证后根据身份来授权(有歧视的嫌疑的东东,本人可是反歧视人士)。

那么JAAS是如何实现认证的呢?又是如何实现授权的呢?且听我慢慢分解,将其妙处展现给大家。

二 JAAS的认证原理

(1) 设置JAAS配置文件,关于配置非常有技巧,跟设置防火墙的过滤规则有得一拼;

(2) 根据JAAS配置文件的条目加载一个或者多个LoginModule(通常一个,也可以变态得使用多个);

(3) 为了管理用户认证的有关过程,将提供一个可选的LoginModule构造函数和一个回调处理器CallbackHandler。如果没有在构造函数中提供回调处理器,系统采用默认设置;

(4) 初始并实例化LoginContext(加载配置规则),如果成功,则调用LoginContext的login方法。无论是否需 要,LoginContext都会去首先读取JAAS配置文件,从中获得要加载的登陆模块信息,其initialize方法将按照配置文件中的相关内容提 供LoginModule运行所需要的信息;

(5) LoginContext的login方法将调用LoginModule的login方法,确定用户身份。该方法将设置相关的回调,并由回调处理器CallbackHandler来管理登陆处理回调;

(6) LoginModule的login方法将负责与用户进行交互(可能是人机交互,也可能是机机交互),如果用户输入信息无效,则该方 法返回FALSE,一次交互过程结束,如果用户输入信息有效,则该方法将设置Principal对象的Subject对象,并返回TRUE;当然 LoginModule也可以将与用户之间的所有交互过程全部委托给处理器CallbackHandler来处理。如果登陆成功, LoginContext将调用LoginModule的commit方法将结果提交给LoginModule实例的内部状态。


 在应用程序中使用JAAS验证通常会涉及到以下几个步骤:

  1. 创建一个LoginContext的实例。

  2. 为了能够获得和处理验证信息,将一个CallBackHandler对象作为参数传送给LoginContext。

  3. 通过调用LoginContext的login()方法来进行验证。

  4. 通过使用login()方法返回的Subject对象实现一些特殊的功能(假设登录成功)。

  下面是一个简单的例子:

      SimpleLogin.java
      

package com;

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

public class SimpleLogin {
	
	public static void main(String[] args) {
		
		// 建立登陆上下文,并通过配置文件初始化,在这里配置文件必须与程序同目录
		LoginContext loginContext = null;
		try {
			                               
			loginContext = new LoginContext("simple", new SimpleCallbackHandle());
		} catch (LoginException e) {
			
			System.out.println(e.getMessage());
		}
		
		try {
			
			// 如果不抛出异常表示验证成功
			loginContext.login();
		} catch (LoginException e) {
			
		}
	}
	
}

 


   
   SimpleCallbackHandle.java
   

package com;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

public class SimpleCallbackHandle implements CallbackHandler {

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

		for (Callback callback : callbacks) {

			if (callback instanceof NameCallback) {
				NameCallback nc = (NameCallback) callback;
				
				System.out.print(nc.getPrompt());
		 		System.out.flush();
		 		
				nc.setName((new BufferedReader(new InputStreamReader(
								System.in))).readLine());
			} else if (callback instanceof PasswordCallback) {
				PasswordCallback pcb = (PasswordCallback) callback;
				
				System.out.print(pcb.getPrompt());
		 		System.out.flush();
				pcb.setPassword((new BufferedReader(new InputStreamReader(
						System.in))).readLine().toCharArray());
			}
		}
	}
}

 

 

 

SimpleLoginModule.java

 

 

package com;

import java.io.IOException;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

public class SimpleLoginModule implements LoginModule{

	private String userName;
	
    private char[] password;
    
    private Subject subject;
    
    private CallbackHandler callbackHandler;
    
    private Map sharedState;
    
    private Map options;
    
    private String debug;
    
	public boolean abort() throws LoginException {
		System.out.println("abort()");
		return false;
	}

	public boolean commit() throws LoginException {
		System.out.println("commit()");
		return false;
	}

	public void initialize(Subject subject, CallbackHandler callbackHandler,
			Map sharedState, Map options) {
		
		this.subject = subject;
		this.callbackHandler = callbackHandler;
		this.sharedState = sharedState;
		this.options = options;
		
		debug = (String)options.get("debug");
	}

	public boolean login() throws LoginException {
		
		Callback[] callbacks = new Callback[2];
		callbacks[0] = new NameCallback("用户名: ");
		callbacks[1] = new PasswordCallback("密码: ", false);
		
		try {
			
			callbackHandler.handle(callbacks);
			userName = ((NameCallback)callbacks[0]).getName();
			password = ((PasswordCallback)callbacks[1]).getPassword();
			
			if(debug.equals("true")){
				System.out.println("你输入的用户名为:" + userName);
				System.out.println("你输入的密码为:" + new String(password));
			}
			
			if(userName.equals("callan") && new String(password).equals("callanpass")){
				System.out.println("验证成功");
				return true;
			} else {
				System.out.println("验证失败");
				userName = null;
				password = null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UnsupportedCallbackException e) {
			e.printStackTrace();
		}
		
		return false;
	}

	public boolean logout() throws LoginException {
		System.out.println("logout()");
		return false;
	}

}

 

 

jaas.config

 

simple {
   com.SimpleLoginModule required debug=true;
};

 

  

将代码编辑通过后执行以下命令:

java -Djava.security.auth.login.config==jaas.config com.SimpleLogin

 

  • core.rar (5.1 KB)
  • 描述: 原代码
  • 下载次数: 555
17
2
分享到:
评论
7 楼 weileniweilewo 2012-02-22  
非常不错,谢谢LZ
6 楼 edgar108 2011-04-01  
应该是这样吧 :java -Djava.security.auth.login.config=jaas.config -cp ./ com.SimpleLogin
5 楼 jackChen86 2010-06-01  
开心^o^就好 写道
我怎么运行不起来啊

因为他是粘别人的
4 楼 duesouth 2009-06-19  
命令有点小错,应该是
java -Djava.security.auth.login.config=jaas.config com.SimpleLogin
3 楼 开心^o^就好 2008-10-07  
我怎么运行不起来啊
2 楼 不是流氓 2008-06-06  
下了你的源代码,但是总是报
无法定位登录配置

请教一下,谢谢
1 楼 jackyxuan 2008-02-25  
顶!good!

相关推荐

    JAAS简介及实例.

    1. 应用程序创建一个LoginContext实例,传入特定的配置信息。 2. 调用LoginContext的login方法启动认证流程。 3. 用户通过CallbackHandler提供认证信息。 4. LoginModule验证信息并设置Subject中的Principal。 5. ...

    JAAS认证与授权教程

    `i`和`j-sec2`可能是文档或示例项目的部分,它们可能提供了关于如何配置和使用JAAS的详细指南,或者展示了如何将JAAS集成到具体的应用服务器如Tomcat或JBoss中的实例。 学习JAAS对于任何希望构建安全Java应用程序的...

    JAAS Demo

    1. **初始化LoginContext**:创建LoginContext实例时需指定一个Configuration对象,该对象包含了LoginModule的配置信息。 2. **调用login()方法**:LoginContext的login()方法启动认证过程,根据配置加载相应的...

    websphere 6 JAAS登陆例子

    总之,这个压缩包文件提供了关于在Websphere 6中使用JAAS和SSO集成LDAP身份验证的实例,对于理解如何在企业级环境中实施安全登录策略具有重要价值。开发者和系统管理员可以通过研究这些材料来提升他们在Java安全架构...

    JAAS样例

    一旦用户通过认证,他们会被表示为一个或多个`Principal`实例,这些实例随后可以用来进行权限检查。 通过这个样例,我们可以学习如何设置JAAS配置,创建自定义登录模块,处理用户输入,记录安全日志,以及如何在...

    基于JAAS的Java安全编程

    ### 基于JAAS的Java安全编程 #### JAAS概览 JAAS(Java Authentication and Authorization Service,Java认证与授权服务)是Sun Microsystems为Java 2平台开发的一套安全框架扩展,旨在加强Java应用程序的安全性。...

    tomcat_jaas_demo

    tomcat下jaas配置实例(文档有不完善的地方) 1、需要修改 bin\startup.bat(根据自己的环境修改) SET JAVA_HOME=C:\programs\Java\jdk1.8.0_211 SET TOMCAT_HOME=C:\programs\apache-tomcat-5.5.20 2、需要修改 bin...

    JAAS认证(mac版tomcat)

    在这里,`MyConfig`是实现`javax.security.auth.login.Configuration`接口的类,负责返回你的LoginModule实例。 4. **打包和部署**:将你的LoginModule类打包成JAR文件,如`jaasTestJar`,并将其放置在Tomcat的`...

    JAAS.rar_Action!_Jaas Kerber_jaas KERBEROS_kerberos Java_login.a

    总结来说,这个资源提供了学习和实践Java中使用JAAS与Kerberos进行安全认证和授权的实例,涵盖了从设置登录模块到执行安全操作的完整流程,对于提升开发者在安全领域的技能非常有帮助。通过深入理解和应用这些概念,...

    JAAS 认证服务

    #### 一、JAAS简介 JAAS(Java Authentication and Authorization Service)是Java平台提供的一种安全框架,用于实现客户端应用程序的安全认证和授权管理。它为Java应用提供了一种灵活的方式来实现安全控制,使得...

    JAAS:灵活的Java安全机制

    - **`LoginContext`类**:创建并管理`LoginModule`实例,控制整个验证流程。 - **`LoginModule`类**:实现具体的验证逻辑,如用户名/密码验证、基于证书的验证等。 - **`CallbackHandler`接口**:用于从用户那里获取...

    JBOSS security using JAAS

    3. **JAAS配置实例** - **LDAP认证**:JBOS可以通过连接到LDAP服务器进行用户认证,配置包括指定 LDAP URL、基DN、搜索过滤器等参数。 - **数据库认证**:如果用户信息存储在数据库中,可以配置数据库模块,如...

    jaas资料 基于JAAS和J2EE Web容器的验证与授权

    #### 五、实例分析 文章提到,在 Borland 应用服务器的基础上,使用 JAAS 与 J2EE Web 容器的内置安全机制,并结合 Oracle 数据库的用户验证功能,实现了 Web 应用中对用户的验证和授权。这种方法的一个关键优势...

    Jaas in Action (java 安全)

    "Jaas in Action"这本书可能会详细解释这些概念,并通过实例演示如何在实际项目中应用JAAS。它可能还会涵盖高级话题,如联合身份验证(Federation)、单点登录(Single Sign-On, SSO)以及与现代Web服务和云环境的...

    安全认证JAASDemo

    ### JAAS简介 JAAS是Java平台提供的一个认证框架,它允许开发人员为应用程序添加强大的用户认证机制,而不必依赖于Java平台本身。JAAS的设计目标是使开发人员能够轻松地将各种认证技术和策略集成到他们的应用程序中...

Global site tag (gtag.js) - Google Analytics