`
samjavaeye
  • 浏览: 193798 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JAAS样例

    博客分类:
  • Java
阅读更多

经过几天研究,终于跑起来了第一个JAAS例子。把代码贴上来,免得以后忘了。

 

MyCallbackHandler.java(处理用户输入)

package com.pingan.jaas.tutorial;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PushbackInputStream;
import java.util.Arrays;

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.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

public class MyCallbackHandler implements CallbackHandler {

	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
		for (int i = 0; i < callbacks.length; i++) {
			if (callbacks[i] instanceof TextOutputCallback) {
				// 根据指定的类型显示信息
				TextOutputCallback toc = (TextOutputCallback) callbacks[i];
				switch (toc.getMessageType()) {
				case TextOutputCallback.INFORMATION:
					System.out.println(toc.getMessage());
					break;
				case TextOutputCallback.ERROR:
					System.out.println("ERROR: " + toc.getMessage());
					break;
				case TextOutputCallback.WARNING:
					System.out.println("WARNING: " + toc.getMessage());
					break;
				default:
					throw new IOException("Unsupported message type: "
							+ toc.getMessageType());
				}
			} else if (callbacks[i] instanceof NameCallback) {
				// 如果命令行没有提供用户名,提示用户输入用户名
				NameCallback nc = (NameCallback) callbacks[i];

				System.err.print(nc.getPrompt());
				System.err.flush();
				nc
						.setName((new BufferedReader(new InputStreamReader(
								System.in))).readLine());
			} else if (callbacks[i] instanceof PasswordCallback) {
				// prompt the user for a password
				PasswordCallback pc = (PasswordCallback) callbacks[i];

				System.err.print(pc.getPrompt());
				System.err.flush();
				pc.setPassword(readPassword(System.in));
			} else {
				throw new UnsupportedCallbackException(callbacks[i],
						"Unrecognized Callback");
			}
		}

	}

	private char[] readPassword(InputStream in) throws IOException {
		char[] lineBuffer;
		char[] buf;

		buf = lineBuffer = new char[128];

		int room = buf.length;
		int offset = 0;
		int c;

		loop: while (true) {
			switch (c = in.read()) {
			case -1:
			case '\n':
				break loop;

			case '\r':
				int c2 = in.read();
				if ((c2 != '\n') && (c2 != -1)) {
					if (!(in instanceof PushbackInputStream)) {
						in = new PushbackInputStream(in);
					}
					((PushbackInputStream) in).unread(c2);
				} else
					break loop;

			default:
				if (--room < 0) {
					buf = new char[offset + 128];
					room = buf.length - offset - 1;
					System.arraycopy(lineBuffer, 0, buf, 0, offset);
					Arrays.fill(lineBuffer, ' ');
					lineBuffer = buf;
				}
				buf[offset++] = (char) c;
				break;
			}
		}

		if (offset == 0) {
			return null;
		}

		char[] ret = new char[offset];
		System.arraycopy(buf, 0, ret, 0, offset);
		Arrays.fill(buf, ' ');

		return ret;
	}

}

 

SampleAcn.java(客户端)

 

package com.pingan.jaas.tutorial;

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

public class SampleAcn {
	public static void main(String[] args) {
		LoginContext lc = null;
		try {
			lc = new LoginContext("test5", new MyCallbackHandler());
		} catch (LoginException le) {
			System.err
					.println("Cannot create LoginContext. " + le.getMessage());
			System.exit(-1);
		} catch (SecurityException se) {
			System.err
					.println("Cannot create LoginContext. " + se.getMessage());
			System.exit(-1);
		}
		// 给用户3次登录机会
		int retryTimes = 3;
		int i;
		for (i = 0; i < retryTimes; i++) {
			try {
				// attempt authentication
				lc.login();
				// if we return with no exception,
				// authentication succeeded
				break;
			} catch (LoginException le) {
				System.err.println("Authentication failed:");
				System.err.println("  " + le.getMessage());
				try {
					Thread.sleep(3000);
				} catch (Exception e) {
					// ignore
				}
			}
		}

		// did they fail three times?
		if (i == retryTimes) {
			System.out.println("Sorry");
			System.exit(-1);
		}

		System.out.println("Authentication succeeded!");

	}
}

 

 

 

SamplePrincipal.java(自定义Principal类

package com.pingan.jaas.tutorial;

import java.security.Principal;

public class SamplePrincipal implements Principal, java.io.Serializable {
	private static final long serialVersionUID = -5974294088673749367L;
	private String name;

	public SamplePrincipal(String name) {
		if (name == null)
			throw new NullPointerException("illegal null input");
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public String toString() {
		return ("SamplePrincipal:  " + name);
	}

	public boolean equals(Object o) {
		if (o == null)
			return false;

		if (this == o)
			return true;

		if (!(o instanceof SamplePrincipal))
			return false;
		SamplePrincipal that = (SamplePrincipal) o;

		if (this.getName().equals(that.getName()))
			return true;
		return false;
	}

	public int hashCode() {
		return name.hashCode();
	}

}

 

 

 

SampleLoginModule.java(自定义登录模块)

package com.pingan.jaas.tutorial;

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.FailedLoginException;
import javax.security.auth.login.LoginException;

import examples.util.LogHelper;

public class SampleLoginModule {
	// initial state
	private Subject subject;
	private CallbackHandler callbackHandler;
	private Map sharedState;
	private Map options;

	// configurable option
	private boolean debug = false;

	// the authentication status
	private boolean succeeded = false;
	private boolean commitSucceeded = false;

	// username and password
	private String username;
	private char[] password;

	// testUser's SamplePrincipal
	private SamplePrincipal userPrincipal;

	public void initialize(Subject subject, CallbackHandler callbackHandler,
			Map sharedState, Map options) {

		this.subject = subject;
		this.callbackHandler = callbackHandler;
		this.sharedState = sharedState;
		this.options = options;

		// initialize any configured options
		debug = "true".equalsIgnoreCase((String) options.get("debug"));
	}

	public boolean login() throws LoginException {
		// prompt for a user name and password
		if (callbackHandler == null)
			throw new LoginException("Error: no CallbackHandler available "
					+ "to garner authentication information from the user");

		Callback[] callbacks = new Callback[2];
		callbacks[0] = new NameCallback("user name: ");
		callbacks[1] = new PasswordCallback("password: ", false);

		try {
			callbackHandler.handle(callbacks);
			username = ((NameCallback) callbacks[0]).getName();
			char[] tmpPassword = ((PasswordCallback) callbacks[1])
					.getPassword();
			if (tmpPassword == null) {
				// treat a NULL password as an empty password
				tmpPassword = new char[0];
			}
			password = new char[tmpPassword.length];
			System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
			((PasswordCallback) callbacks[1]).clearPassword();

		} catch (java.io.IOException ioe) {
			throw new LoginException(ioe.toString());
		} catch (UnsupportedCallbackException uce) {
			throw new LoginException("Error: " + uce.getCallback().toString()
					+ " not available to garner authentication information "
					+ "from the user");
		}

		// print debugging information
		if (debug) {
			System.out.println("\t\t[SampleLoginModule] "
					+ "user entered user name: " + username);
			System.out.print("\t\t[SampleLoginModule] "
					+ "user entered password: ");
			for (int i = 0; i < password.length; i++)
				System.out.print(password[i]);
			System.out.println();
		}

		// 校验用户名和密码(用户名为testUser,密码为testPassword,区分大小写)
		boolean usernameCorrect = false;
		boolean passwordCorrect = false;
		if (username.equals("testUser"))
			usernameCorrect = true;
		if (usernameCorrect && password.length == 12 && password[0] == 't'
				&& password[1] == 'e' && password[2] == 's'
				&& password[3] == 't' && password[4] == 'P'
				&& password[5] == 'a' && password[6] == 's'
				&& password[7] == 's' && password[8] == 'w'
				&& password[9] == 'o' && password[10] == 'r'
				&& password[11] == 'd') {

			// authentication succeeded!!!
			passwordCorrect = true;
			if (debug)
				System.out.println("\t\t[SampleLoginModule] "
						+ "authentication succeeded");
			succeeded = true;
			return true;
		} else {

			// authentication failed -- clean out state
			if (debug)
				System.out.println("\t\t[SampleLoginModule] "
						+ "authentication failed");
			succeeded = false;
			username = null;
			for (int i = 0; i < password.length; i++)
				password[i] = ' ';
			password = null;
			if (!usernameCorrect) {
				throw new FailedLoginException("User Name Incorrect");
			} else {
				throw new FailedLoginException("Password Incorrect");
			}
		}
	}

	public boolean commit() throws LoginException {
		LogHelper.log2Console("succeeded=" + succeeded);
		if (succeeded == false) {
			return false;
		} else {
			// add a Principal (authenticated identity)
			// to the Subject

			// assume the user we authenticated is the SamplePrincipal
			userPrincipal = new SamplePrincipal(username);
			if (!subject.getPrincipals().contains(userPrincipal))
				subject.getPrincipals().add(userPrincipal);

			if (debug) {
				System.out.println("\t\t[SampleLoginModule] "
						+ "added SamplePrincipal to Subject");
			}

			// in any case, clean out state
			username = null;
			for (int i = 0; i < password.length; i++)
				password[i] = ' ';
			password = null;

			commitSucceeded = true;
			return true;
		}
	}

	public boolean abort() throws LoginException {
		LogHelper.log2Console("succeeded=" + succeeded);
		if (succeeded == false) {
			return false;
		} else if (succeeded == true && commitSucceeded == false) {
			// login succeeded but overall authentication failed
			succeeded = false;
			username = null;
			if (password != null) {
				for (int i = 0; i < password.length; i++)
					password[i] = ' ';
				password = null;
			}
			userPrincipal = null;
		} else {
			// overall authentication succeeded and commit succeeded,
			// but someone else's commit failed
			logout();
		}
		return true;
	}

	public boolean logout() throws LoginException {
		subject.getPrincipals().remove(userPrincipal);
		succeeded = false;
		succeeded = commitSucceeded;
		username = null;
		if (password != null) {
			for (int i = 0; i < password.length; i++)
				password[i] = ' ';
			password = null;
		}
		userPrincipal = null;
		return true;
	}

}

 

该类没有实现javax.security.auth.spi.LoginModule接口,似乎也可以运行。为简单起见,代码里面用户名固定为testUser,密码固定为testPassword 

 

 

 

还有一个MyLoginModule类,跟SampleLoginModule类是一样的,只是修改了硬编码的用户名和密码,便于测试。

 

Sample_jaas.configJAAS配置文件)

Sample {
   com.pingan.jaas.tutorial.SampleLoginModule required debug=true;
};
Sample2 {
   com.pingan.jaas.tutorial.MyLoginModule required debug=true;
};
all_required {
	com.pingan.jaas.tutorial.SampleLoginModule required debug=true;
	com.pingan.jaas.tutorial.MyLoginModule required debug=true;	
};
test3 {
	com.pingan.jaas.tutorial.SampleLoginModule required debug=true;
	com.pingan.jaas.tutorial.MyLoginModule Sufficient debug=true;
};
test4 {
	com.pingan.jaas.tutorial.MyLoginModule Sufficient debug=true;
	com.pingan.jaas.tutorial.SampleLoginModule required debug=true;
};
test5 {
	com.pingan.jaas.tutorial.MyLoginModule Optional debug=true;
	com.pingan.jaas.tutorial.SampleLoginModule required debug=true;
};

 

 

 

 

为了测试不同情况,配置了多个组合,具体使用哪个组合,在上文中客户端代码指定。

 

 编译后运行客户端,需要在命令行指定JAAS配置文件位置,参考命令行如下:

java -Djava.security.auth.login.config=com/pingan/jaas/tutorial/sample_jaas.config -cp ".;%CLASSPATH%;C:\bea\weblogic81\server\lib\weblogic.jar;C:\bea\weblogic81\server\lib\mbeantypes\wlManagement.jar;" com.pingan.jaas.tutorial.SampleAcn

 

运行结果:

C:\bea\user_projects\applications\Test3\Test3Web\WEB-INF\classes>java -Djava.security.auth.login.config=com/pingan/jaas/tutorial/sample_jaas.config -cp ".;%CLASSPATH%;C:\bea\weblogic81\server\lib\weblogic.jar;C:\bea\weblogic81\server\lib\mbeantypes\wlManagement.jar;" com.pingan.jaas.tutorial.SampleAcn
user name: testUser
password: testPassword
                [MyLoginModule] 用户输入的用户名: testUser
                [MyLoginModule] 用户输入的密码:testPassword
                [MyLoginModule] authentication failed
user name: testUser
password: testPassword
                [SampleLoginModule] user entered user name: testUser
                [SampleLoginModule] user entered password: testPassword
                [SampleLoginModule] authentication succeeded

com.pingan.jaas.tutorial.MyLoginModule.commit(131)
---------------------------------- <2011-02-14 10:03:14> ----------------------------------
succeeded=false
---------------------------------- <2011-02-14 10:03:14> ----------------------------------


com.pingan.jaas.tutorial.SampleLoginModule.commit(131)
---------------------------------- <2011-02-14 10:03:14> ----------------------------------
succeeded=true
---------------------------------- <2011-02-14 10:03:14> ----------------------------------

                [SampleLoginModule] added SamplePrincipal to Subject
Authentication succeeded!

 

还有一个帮助类LogHelper.java:

package examples.util;

import java.text.SimpleDateFormat;
import java.util.Date;

public class LogHelper {
	private static final String 换行符 = "\r\n";
	private static final String 分隔线 = "----------------------------------";
	private static final SimpleDateFormat sf = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	public static void log2Console(String msg) {
		StackTraceElement[] stackTraceElements = new Throwable()
				.getStackTrace();
		StackTraceElement stackTraceElement = stackTraceElements[1];

		StringBuffer sb = new StringBuffer();
		// sb.append(换行符);
		sb.append(换行符).append(stackTraceElement.getClassName());
		sb.append('.');
		sb.append(stackTraceElement.getMethodName()).append("(");
		sb.append(stackTraceElement.getLineNumber()).append(")");
		sb.append(换行符);
		String separateLine = buildSeparateLine();
		sb.append(separateLine);
		sb.append(msg).append(换行符);
		sb.append(separateLine);
		System.out.println(sb.toString());
	}

	public static void log2Console(String[] array) {
		StackTraceElement[] stackTraceElements = new Throwable()
				.getStackTrace();
		StackTraceElement stackTraceElement = stackTraceElements[1];

		StringBuffer sb = new StringBuffer();
		// sb.append(换行符);
		sb.append(换行符).append(stackTraceElement.getClassName());
		sb.append('.');
		sb.append(stackTraceElement.getMethodName()).append("(");
		sb.append(stackTraceElement.getLineNumber()).append(")");
		sb.append(换行符);
		String separateLine = buildSeparateLine();
		sb.append(separateLine);
		if (array == null) {
			sb.append("数组为空(NULL)").append(换行符);
		} else {
			sb.append('{');
			for (int i = 0; i < array.length; i++) {
				if (i >= 0) {
					sb.append(", ");
				}
				sb.append('"').append(array[i]).append('"');
			}
			sb.append('}').append(换行符);
		}
		sb.append(separateLine);
		System.out.println(sb.toString());
	}

	private static String buildSeparateLine() {
		StringBuffer sb = new StringBuffer();
		Date currentTime = new Date();
		sb.append(分隔线).append(" <").append(sf.format(currentTime)).append("> ")
				.append(分隔线).append(换行符);
		return sb.toString();
	}
}

 

分享到:
评论

相关推荐

    jaas.jar jaas.jar

    jaas.jar jaas.jar jaas.jar

    JAAS简介及实例

    Java Authentication and Authorization Service (JAAS) 是Java平台提供的一种安全框架,用于实现用户身份验证和权限管理。这个框架使得开发者可以轻松地在Java应用程序中集成安全性,而不必深入理解底层的复杂安全...

    JAAS简介及示例代码

    Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的核心组件,它为开发者提供了一种机制来处理用户身份验证和权限控制。这个服务允许应用程序执行基于角色的安全性,这意味着用户的...

    jaas规范实现代码

    Java Authentication and Authorization Service (JAAS) 是 Java 平台中用于安全管理的重要组件,它提供了一种框架,使得应用程序可以进行用户身份验证和权限控制。在本文中,我们将深入探讨 JAAS 的核心概念、工作...

    java JAAS登陆验证

    Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的框架,主要用于用户身份验证和权限授权。在Java应用程序中,尤其是服务器端应用,确保只有合法的用户能够访问资源是至关重要的。...

    JAAS认证与授权教程

    Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的关键组件,它提供了一种框架,使得应用程序能够实现用户身份验证和权限管理。在这个教程中,我们将深入探讨JAAS的核心概念、工作...

    JAAS in Web Applications

    Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的关键组件,它提供了一种标准框架来实现用户身份验证和授权。在Web应用程序中,JAAS被用来控制对资源的访问,确保只有经过验证的用户...

    JAAS In Action download

    **Java Authentication and Authorization Service (JAAS) 深入解析** JAAS,全称为Java Authentication and Authorization Service,是Java平台中的一个核心组件,用于处理应用系统的用户身份验证和权限授权。这个...

    jaas详细配置精讲

    Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全认证和授权的核心组件。它为开发者提供了一种标准的方式来管理用户的身份验证和访问控制,从而确保应用程序的安全性。在本精讲中,我们...

    java软件包文件 jaas.jar

    Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全性的关键组件,它提供了一种框架,用于在Java应用程序中实现认证(Authentication)和授权(Authorization)。`jaas.jar` 文件是这个...

    JAAS登录验证文档

    ### JAAS登录验证知识点 #### 一、JAAS概述 Java Authentication and Authorization Service(JAAS)是Java平台提供的一种安全框架,它允许开发者为应用程序添加认证和授权功能。与传统的基于容器的身份验证不同,...

    websphere 6 JAAS登陆例子

    标题 "websphere 6 JAAS登陆例子" 描述了一个在Websphere 6版本中集成LDAP用户和实现Single Sign-On (SSO)的实践案例。这个主题涉及到Java Authentication and Authorization Service (JAAS)的安全框架,以及它如何...

    JAAS Demo

    ### JAAS基础知识与应用 #### 一、JAAS概述 JAAS(Java Authentication and Authorization Service)作为Java平台标准版(JSE)的一部分,为Java应用程序提供了灵活且强大的身份验证和授权服务。相比于早期版本的...

    JAAS简介及实例.

    Java Authentication and Authorization Service (JAAS) 是Java平台中用于安全管理的框架,它是Java Cryptography Extension (JCE) 安全框架的重要补充。JAAS的主要目标是提供用户认证和授权服务,确保应用程序能...

    jaas j2se例子

    jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas j2se例子jaas ...

    基于JAAS的Java安全编程

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

Global site tag (gtag.js) - Google Analytics