`
kylinsoong
  • 浏览: 240058 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

EJB Security & JAAS Demo

阅读更多

PROLOGUE:

      When deploying enterprise application like EJB on some enterprise-based container, we also need to bound lots of important busniss resource with our application. Important means critical, security can be one of most important aspect what we should think about when we building our application. There are so many resouce and articles about javaEE security, this piece belongs to this kinds eithier, the theme  center on EJB Security, but the understanding of java security API is the starting, below is Outline of this piece:

      Java Security API Introducing;

      JAAS Overview;

      Authentication in EJB;

      Authorization in EJB.

 

Java Security API Introducing

      Since Java 2 SDK v1.4, Java security API has became a sophisticated and robust part of SDK, here are some much more related to this article:

(1) javax.security.auth.Subject

      Subjects may potentially have multiple identities. Each identity is represented as a Principal within the Subject;A Subject may also own security-related attributes, which are referred to as credentials, there are teo kinds of credentials, one is sensitive sredentials which need to be protected, are stored in a private credentials set, the other is public credentials which need to be shared, are stored in a public credentials set. javax.security.auth.Subject has supplyed Methods to interact with its Principal, both private credentials and public credentials, as following:

subject.getPrincipals(); 
subject.getPrivateCredentials(); 
subject.getPublicCredentials();

(2) java.security.Principal

       Principal is a Interface, its represents the abstract notion of a principal, which can be used to represent any entity, such as an individual, a corporation, and a login id. The interface has a getName() method which simply bind a name to the Subject. When we pass the authentication we should add our principal to Subject's principal set.

(3) javax.resource.spi.security.PasswordCredential

      PasswordCredential acts as a holder for username and password, its treated as a private credentials in our Part 2 example, its also need to add Subjects private credential set when was been authenticated successfully.

(4) javax.security.auth.spi.LoginModule

      LoginModule is a interface implemented by authentication technology providers, which provide a particular type of authentication use 5 methods:

abort() 
commit() 
initialize(Subject subject, CallbackHandler callbackHandler, Map<String,?> sharedState, Map<String,?> options) 
login() 
logout() 

 this method usually invoked by LoginContext which responsible for reading the Configuration and instantiating the appropriate LoginModules. Each LoginModule is initialized with a Subject, a CallbackHandler, shared LoginModule state, and LoginModule-specific options. The Subject represents the Subject currently being authenticated and is updated with relevant Credentials if authentication succeeds. 

(5) javax.security.auth.callback.Callback

      Implementations of this interface are passed to a CallbackHandler, allowing underlying security services the ability to interact with a calling application to retrieve specific authentication data such as usernames and passwords, in our Part 2 example we use Callback's Implementing Classes NameCallback and PasswordCallback.

(6) javax.security.auth.callback.CallbackHandler

      A interface owns a method handle(Callback[] callbacks) which handle the passed callbacks

(7) javax.security.auth.login.LoginContext

      The LoginContext class describes the basic methods used to authenticate Subjects and provides a way to develop an application independent of the underlying authentication technology. A Configuration specifies the authentication technology, or LoginModule, to be used with a particular application, auth.conf can be found under JBOSS_HOME\client which is the configuration file define the JBOSS login module.

 

JAAS Authentication Overview

      Actually, the above class and interface I have listed that enables you to authenticate users in java, we all known that JAAS has a flexible design, its surprisingly complicated for us to learn. I planed to complete this section combine a authentication example and a figure to make it easier to understand.

      The following figure show the basic JAAS authentication procedure:



       1. The client instantiates a new login context. This is a container-provided class. It’s responsible for coordinating the authentication process.

LoginContext loginContext = new LoginContext("HomeTestClient", new MyCallbackHandler());

Instantiate a new LoginContext object with a name which refered to a loginModule in Configuration file, and MyCallbackHandler which create by our use to handle the passed callbacks.

      2. The login context retrieves a configuration object. The configuration object knows about the type of authentication you want to achieve by consulting a configuration file that lists the login modules. the configuration object is underlying Object, we do not need think about more, but  configuration file we should supply and need to set to JVM when the JVM starting, the following is our exampless configuration file:

default {
	home.jaas.HomeLoginModule required debug=false;
};

HomeTestClient {
	home.jaas.HomeLoginModule required debug=false;
};

  configuration file names auth.conf, under resurce folder, we should set to JVM like below code depicted:

File authFile = new File("resource/auth.conf");
System.setProperty("java.security.auth.login.config", "file:///" + authFile.getAbsolutePath());

      3. The login context asks the configuration object for the list of authentication
mechanisms to use (such as password-based and certificate-based). in our example we use  password-based authentication mechanism.

      4. The configuration object returns a list of authentication mechanisms. Each one is called a login module. A login module knows how to contact a specific security provider and authenticate in some proprietary way.

      5. The login context instantiates your login modules. You can have many login modules if you want to authenticate across several different security providers. In the example we’re about to show, we will use only one login module, and it will know how to authenticate using a user name and password combination to a Java EE server.

      6. The login context initializes the login modules. login context invoke loginModule's initialize() method:

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

      7. The client code tries to log in by calling the login() method on the login context.

loginContext.login();

      8. The login context delegates the login() call to the login modules, since only the login modules know how to perform the actual authentication. which in this section  loginModule's login method has been invoked. the main code:

callbackHandler.handle(callbacks);
if(username.equals("admin") && "admin".equals(new String(password))) {
	return true;
} 

      9. The login modules (written by you) authenticate you using a proprietary means. In the example we’re about to show, the user name and password login module will perform a local authentication only that admin and admin has been passed it succeeds. After the login succeeds, the login module is told to commit(). It can also abort() if the login process fails. the hightlight code in commit method:

PasswordCredential pc = new PasswordCredential(username, password);
subject.getPrivateCredentials().add(pc);

the above code shows that our private credentials has been add to Subject's private credentials set. 

      10. Authentication information is kept in a subject. You can use this subject to perform secure operations or just have it sit in the context.

      11. Your client code calls remote operations (such as in an EJB component) and the logged-in security context is automatically propagated along with the method call.

I will give the complete code of this example:

HomeTestClient.java

public class HomeTestClient {
	public static Logger logger = Logger.getLogger(HomeTestClient.class);
	public static void main(String[] args) {
		logger.debug("JAAS Example Starting...");
		File authFile = new File("resource/auth.conf");
		logger.debug("Client-side Configuration File Location: " + authFile.getAbsolutePath());
		System.setProperty("java.security.auth.login.config", "file:///" + authFile.getAbsolutePath());
		logger.debug("JVM Property 'java.security.auth.login.config' Set Completed");
		try {
			LoginContext loginContext = new LoginContext("HomeTestClient", new MyCallbackHandler());
			loginContext.login();
		} catch (LoginException e) {
			e.printStackTrace();
		} 
		System.out.println("Invoke the method secuely");
	}
}

 HomeLoginModule.java

public class HomeLoginModule implements LoginModule {
	private static Logger logger = Logger.getLogger(HomeLoginModule.class);
	private Subject subject;
	private CallbackHandler callbackHandler;
	private String username;
	private char[] password;
	public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
		logger.debug("initialize()");
		this.subject = subject;
		this.callbackHandler = callbackHandler;
	}
	
	public boolean login() throws LoginException {
		logger.debug("login()");
		if(callbackHandler == null) {
			throw new LoginException("Error: No callbackHandler available to collect authentication information");
		}
		Callback[] callbacks = new Callback[2];
		callbacks[0] = new NameCallback("Username: ");
		callbacks[1] = new PasswordCallback("Password: ", false);
		try {
			callbackHandler.handle(callbacks);
			username = ((NameCallback) callbacks[0]).getName();
			if(username == null) {
				throw new LoginException("No user specified");
			}
			char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
			if(tmpPassword == null) {
				tmpPassword = new char[0];
			}
			password = new char[tmpPassword.length];
			System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
			((PasswordCallback) callbacks[1]).clearPassword();
		} catch (IOException e) {
			throw new LoginException(e.getMessage());
		} catch (UnsupportedCallbackException e) {
			throw new LoginException("Error: No callback available to authentication data: " + e.getMessage());
		}
		//authentication
		if(username.equals("admin") && "admin".equals(new String(password))) {
			return true;
		} 
		return false;
	}
	
	public boolean commit() throws LoginException {
		logger.debug("commit()");
		PasswordCredential pc = new PasswordCredential(username, password);
		subject.getPrivateCredentials().add(pc);
		username = null;
		password = null;
		return true;
	}

	public boolean abort() throws LoginException {
		logger.debug("abort()");
		return true;
	}

	public boolean logout() throws LoginException {
		logger.debug("logout()");
		username = null;
		password = null;
		return true;
	}
}

 MyCallbackHandler.java

public class MyCallbackHandler implements CallbackHandler {
	private static Logger logger = Logger.getLogger(MyCallbackHandler.class);
	public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
		logger.debug("handle method invoked, handle callbacks.");
		for(int i = 0 ; i < callbacks.length ; i++) {
			if(callbacks[i] instanceof NameCallback) {
				NameCallback nc = (NameCallback) callbacks[i];
				System.out.print(nc.getPrompt());
				String name = (new BufferedReader(new InputStreamReader(System.in))).readLine();
				nc.setName(name);
				logger.debug("NameCallback Set Name: " + name);
			} else if(callbacks[i] instanceof PasswordCallback) {
				PasswordCallback pc = (PasswordCallback) callbacks[i];
				System.out.print(pc.getPrompt());
				String pwLine = (new BufferedReader(new InputStreamReader(System.in))).readLine();
				pc.setPassword(pwLine.toCharArray());
				logger.debug("PasswordCallback Set Password: " + pwLine);
			} else {
				logger.error("Unrecognized Callback");
				throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
			}
		}
	}
}

   Run the HomeTestClient class, input admin when username prompt came out, and same input admin when password prompt came out, the authentication successful result will show:

and also in log file you will find the authentication procedure log recorded by log4j:

   2011:05:21 - 19:30:32 [home.jaas.HomeTestClient] DEBUG - JAAS Example Starting...
   2011:05:21 - 19:30:32 [home.jaas.HomeTestClient] DEBUG - Client-side Configuration File Location: D:\dev-workspaces\home\com.home.ear.v2\resource\auth.conf
   2011:05:21 - 19:30:32 [home.jaas.HomeTestClient] DEBUG - JVM Property 'java.security.auth.login.config' Set Completed
   2011:05:21 - 19:30:32 [home.jaas.HomeLoginModule] DEBUG - initialize()
   2011:05:21 - 19:30:32 [home.jaas.HomeLoginModule] DEBUG - login()
   2011:05:21 - 19:30:32 [home.jaas.MyCallbackHandler] DEBUG - handle method invoked, handle callbacks.
   2011:05:21 - 19:30:36 [home.jaas.MyCallbackHandler] DEBUG - NameCallback Set Name: admin
   2011:05:21 - 19:30:38 [home.jaas.MyCallbackHandler] DEBUG - PasswordCallback Set Password: admin
   2011:05:21 - 19:30:38 [home.jaas.HomeLoginModule] DEBUG - commit()

 

Understanding EJB Security

    There are two security measures that clients must pass when you add security to an EJB system: authentication and authorization. Authentication must be performed before any EJB method is called. Authorization, on the other hand, occurs at the beginning of each EJB method call.


  

  • 大小: 23.5 KB
  • 大小: 5.7 KB
0
1
分享到:
评论

相关推荐

    JBoss4.2.3GA + EJB3.0 + JAAS

    【JBoss4.2.3GA + EJB3.0 + JAAS】是企业级Java应用服务器、EJB(Enterprise JavaBeans)版本和安全性框架JAAS(Java Authentication and Authorization Service)的一个经典组合。这个组合在Java开发领域具有重要的...

    EJB消息驱动bean Demo

    在这个“EJB消息驱动bean Demo”中,我们将深入探讨EJB MDB和JMS如何协同工作以实现异步通信。 首先,JMS是Java平台上的标准API,它定义了生产、发送、接收和消费消息的接口。JMS提供两种消息模型:点对点(Point-...

    ejb&&javascript-pdf

    在IT行业中,`EJB(Enterprise JavaBeans)`和`JavaScript`是两种完全不同的技术,它们在企业级应用开发中各自扮演着重要角色。而`PDF(Portable Document Format)`是一种广泛使用的文档格式,用于存储和共享具有...

    Exercise-EJB.rar_DEMO_ejb demo

    【标题】"Exercise-EJB.rar_DEMO_ejb demo" 提示我们这是一个关于EJB(Enterprise JavaBeans)技术的练习项目,可能包含一个演示了EJB3与JPA(Java Persistence API)集成的实例。EJB是Java EE平台的核心组件,主要...

    JBOSS security using JAAS

    - **配置**:在JBOS中,JAAS通过安全域(Security Domain)进行配置,每个安全域可以有自己的认证和授权策略。配置文件通常位于`$JBOSS_HOME/standalone/configuration/login-config.xml`或`$JBOSS_HOME/domain/...

    Idea搭建EJB架构Demo项目源代码

    【标题】"Idea搭建EJB架构Demo项目源代码"涉及的是使用IntelliJ IDEA(简称Idea)这个强大的Java集成开发环境来构建一个基于EJB(Enterprise JavaBeans)架构的示例项目。EJB是Java EE(企业版)平台的核心部分,...

    EJB2.rar_ejb 2.0 demo_ejb2_ejb2 demo

    本教程"ejb 2.0 demo"旨在帮助学习者理解并掌握EJB 2.0的关键概念和技术。 EJB 2.0的核心组件包括三种Bean类型: 1. **会话Bean(Session Beans)**:这些组件代表了客户端的业务逻辑,可以是单例或会话类型的。...

    ejb3.x 简单小 demo

    标题中的“ejb3.x 简单小 demo”指的是一个关于企业级JavaBeans(EJB)3.x版本的示例项目。EJB是Java平台上的一个组件模型,主要用于构建可部署在Java应用服务器上的分布式、面向服务的企业级应用程序。EJB 3.x是一...

    EJB拦截器的Demo

    在"remote-ejb-with-security-sample"这个示例中,我们可能看到了一个演示如何将EJB拦截器与远程EJB和安全性结合使用的例子。这可能涉及到以下内容: **远程EJB**:EJB不仅可以本地调用,还可以通过RMI(远程方法...

    EJB&Webservice

    EJB&Webservice

    WebLogic v9.2 EJB和JNDI Demo

    WebLogic v9.2 EJB和JNDI Demo

    ejb_demo

    A demo for EJB.

    EJB&Spring;详细对比

    ### EJB与Spring详细对比分析 #### 一、引言 在现代企业级应用开发领域,EJB(Enterprise JavaBeans)与Spring框架均扮演着重要角色。随着技术的发展与需求的变化,两者之间的对比成为了业界广泛关注的话题。本文...

    ejb sessionbean demo

    在"ejb sessionbean demo"中,我们主要探讨的是如何使用EJB的Session Bean进行开发和演示。Session Bean通常用于实现业务逻辑,它们可以是无状态的,意味着每个请求都会创建一个新的Bean实例,不保留任何先前会话的...

    WebLogic v9.2 EJB和JNDI demo 建表语句sql

    WebLogic v9.2 EJB和JNDI demo 建表语句sql

    基于glassfish的EJBDemo,包含打包脚本,包含客户端

    **基于Glassfish的EJBDemo详解** EJB(Enterprise JavaBeans)是Java EE平台中的核心组件,用于构建可扩展的、安全的、事务处理的分布式应用程序。在本EJBDemo中,我们重点关注如何在Glassfish服务器上开发和部署...

    JBoss Myeclipse EJB3 First Demo

    【JBoss Myeclipse EJB3 First Demo】是面向初学者的一个教程,旨在引导大家了解并实践EJB3(Enterprise JavaBeans 3)技术。EJB3是Java EE(Java Platform, Enterprise Edition)规范的一部分,它提供了一种用于...

    EJB模式开发的CMSDemo

    **CMSDemo基于EJB模式开发详解** CMSDemo是一款基于Java技术构建的内容管理系统(Content Management System)的演示项目,它展示了如何结合Struts框架与Enterprise JavaBeans(EJB)技术来实现一个功能丰富的Web...

    JBoss Myeclipse EJB3 Second Demo

    【JBoss Myeclipse EJB3 Second Demo】是基于JBoss应用服务器和MyEclipse集成开发环境的一个EJB3(Enterprise JavaBeans 3)实战示例。EJB3是Java EE(Enterprise JavaBeans)规范的一个版本,它简化了EJB的开发过程...

    EJB+Annotation实现AOP的DEMO

    这篇博客"使用EJB+Annotation实现AOP的DEMO"主要介绍了如何在EJB中利用注解(Annotation)来实现AOP的功能。在Java EE中,EJB 3.0及后续版本引入了大量的注解,使得开发者可以免去编写XML配置文件,直接在代码中声明...

Global site tag (gtag.js) - Google Analytics