An Introduction to JAAS


The JBossSX framework is based on the JAAS API. It is important that you understand the basic elements of the JAAS API to understand the implementation details of JBossSX. The following sections provide an introduction to JAAS to prepare you for the JBossSX architecture discussion later in this chapter.

What Is JAAS?

The JAAS 1.0 API consists of a set of Java packages that are designed for user authentication and authorization. It implements a Java version of the standard Pluggable Authentication Module (PAM) framework and compatibly extends the Java 2 platform's access control architecture to support user-based authorization. JAAS was first released as an extension package for JDK 1.3 and is bundled with JDK 1.4+. Because the JBossSX framework uses only the authentication capabilities of JAAS to implement the declarative role-based J2EE security model, this introduction focuses on only that topic.

JAAS authentication is performed in a pluggable fashion. This permits Java applications to remain independent from underlying authentication technologies and allows the JBossSX security manager to work in different security infrastructures. Integration with a security infrastructure can be achieved without changing the JBossSX security manager implementation. All that needs to change is the configuration of the authentication stack that JAAS uses.

The JAAS Core Classes

The JAAS core classes can be broken down into three categories: common, authentication, and authorization. The following list presents only the common and authentication classes because these are the specific classes used to implement the functionality of JBossSX that is covered in this chapter.

These are the common classes:

  • Subject (javax.security.auth.Subject)

  • Principal (java.security.Principal)

These are the authentication classes:

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

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

  • Configuration (javax.security.auth.login.Configuration)

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

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

The Subject and Principal Classes

To authorize access to resources, applications first need to authenticate the request's source. The JAAS framework defines the term subject to represent a request's source. The Subject class is the central class in JAAS. A Subject represents information for a single entity, such as a person or service. It encompasses the entity's principals, public credentials, and private credentials. The JAAS APIs use the existing Java 2 java.security.Principal interface to represent a principal, which is essentially just a typed name.

During the authentication process, a subject is populated with associated identities, or principals. A subject may have many principals. For example, a person may have a name principal (John Doe), a Social Security number principal (123-45-6789), and a username principal (johnd), all of which help distinguish the subject from other subjects. To retrieve the principals associated with a subject, two methods are available:

 public Set getPrincipals() {...} public Set getPrincipals(Class c) {...} 

The first method returns all principals contained in the Subject. The second method returns only those principals that are instances of class c or one of its subclasses. An empty set is returned if the Subject has no matching principals. Note that the java.security.acl.Group interface is a subinterface of java.security.Principal, so an instance in the principals set may represent a logical grouping of other principals or groups of principals.

Authentication of a Subject

Authentication of a subject requires JAAS login. The login procedure consists of the following steps:

1.

An application instantiates a LoginContext and passes in the name of the login configuration and a Callback-Handler to populate the Callback objects, as required by the configuration LoginModules.

2.

The LoginContext consults a Configuration to load all the LoginModules included in the named login configuration. If no such named configuration exists, the other configuration is used as a default.

3.

The application invokes the LoginContext.login method.

4.

The login method invokes all the loaded LoginModules. As each LoginModule attempts to authenticate the subject, it invokes the handle method on the associated CallbackHandler to obtain the information required for the authentication process. The required information is passed to the handle method in the form of an array of Callback objects. Upon success, the LoginModules associate relevant principals and credentials with the subject.

5.

The LoginContext returns the authentication status to the application. Success is represented by a return from the login method. Failure is represented through a LoginException being thrown by the login method.

6.

If authentication succeeds, the application retrieves the authenticated subject by using the LoginContext.getSubject method.

7.

After the scope of the subject authentication is complete, you can remove all principals and related information associated with the subject by the login method by invoking the LoginContext.logout method.

The LoginContext class provides the basic methods for authenticating subjects and offers a way to develop an application, independently of the underlying authentication technology. The LoginContext consults a Configuration to determine the authentication services configured for a particular application. LoginModule classes represent the authentication services. Therefore, you can plug different login modules into an application without changing the application itself. The following code shows the steps required by an application to authenticate a Subject:

 CallbackHandler handler = new MyHandler(); LoginContext lc = new LoginContext("some-config", handler); try {     lc.login();     Subject subject = lc.getSubject(); } catch(LoginException e) {     System.out.println("authentication failed");     e.printStackTrace(); } // Perform work as authenticated Subject // ... // Scope of work complete, logout to remove authentication info try {     lc.logout(); } catch(LoginException e) {     System.out.println("logout failed");     e.printStackTrace(); } // A sample MyHandler class class MyHandler     implements CallbackHandler {     public void handle(Callback[] callbacks) throws         IOException, UnsupportedCallbackException     {         for (int i = 0; i < callbacks.length; i++) {             if (callbacks[i] instanceof NameCallback) {                 NameCallback nc = (NameCallback)callbacks[i];                 nc.setName(username);             } else if (callbacks[i] instanceof PasswordCallback) {                 PasswordCallback pc = (PasswordCallback)callbacks[i];                 pc.setPassword(password);             } else {                 throw new UnsupportedCallbackException(callbacks[i],                                                        "Unrecognized Callback");             }         }     } } 

To integrate, you can use an authentication technology by creating an implementation of the LoginModule interface. This allows an administrator to plug different authentication technologies into an application. You can chain together multiple LoginModules to allow for more than one authentication technology to participate in the authentication process. For example, one LoginModule may perform username/password-based authentication, while another may interface to hardware devices such as smart card readers or biometric authenticators.

The life cycle of a LoginModule is driven by the LoginContext object against which the client creates and issues the login method. The two-phase process consists of the following steps:

1.

The LoginContext creates each configured LoginModule by using its public no-arg constructor.

2.

Each LoginModule is initialized with a call to its initialize method. The Subject argument is guaranteed to be non-null. The signature of the initialize method is public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options).

3.

The login method is called to start the authentication process. For example, a method implementation might prompt the user for a username and password and then verify the information against data stored in a naming service such as NIS or LDAP. Alternative implementations might interface to smart cards and biometric devices, or they might simply extract user information from the underlying operating system. The validation of user identity by each LoginModule is considered Phase 1 of JAAS authentication. The signature of the login method is boolean login()throws LoginException. A LoginException being thrown indicates failure. A return of true indicates that the method succeeded, whereas a return of false indicates that the login module should be ignored.

4.

If the LoginContext's overall authentication succeeds, commit is invoked on each LoginModule. If Phase 1 succeeds for a LoginModule, then the commit method continues with Phase 2: associating relevant principals, public credentials, and/or private credentials with the subject. If Phase 1 fails for a LoginModule, then commit removes any previously stored authentication state, such as usernames or passwords. The signature of the commit method is boolean commit() throws LoginException. A LoginException being thrown indicates failure to complete the commit phase. A return of TRue indicates that the method succeeded, whereas a return of false indicates that the login module should be ignored.

5.

If the LoginContext's overall authentication fails, then the abort method is invoked on each LoginModule. The abort method removes or destroys any authentication state created by the login or initialize methods. The signature of the abort method is boolean abort() throws LoginException. A LoginException being thrown indicates failure to complete the abort phase. A return of true indicates that the method succeeded, whereas a return of false indicates that the login module should be ignored.

6.

When the application invokes logout on the LoginContext, the authentication state is removed after a successful login. This in turn results in a logout method invocation on each LoginModule. The logout method removes the principals and credentials originally associated with the subject during the commit operation. Credentials should be destroyed upon removal. The signature of the logout method is boolean logout() throws LoginException. A LoginException being thrown indicates failure to complete the logout process. A return of TRue indicates that the method succeeded, whereas a return of false indicates that the login module should be ignored.

When a LoginModule must communicate with the user to obtain authentication information, it uses a CallbackHandler object. Applications implement the CallbackHandler interface and pass it to the LoginContext, which forwards it directly to the underlying login modules. Login modules use the CallbackHandler both to gather input from users, such as a password or smart card PIN, and to supply information to users, such as status information. By allowing the application to specify the CallbackHandler, underlying LoginModules remain independent from the different ways applications interact with users. For example, a CallbackHandler's implementation for a GUI application might display a window to solicit user input. On the other hand, a callbackhandler's implementation for a non-GUI environment, such as an application server, might simply obtain credential information by using an application server API. The callbackhandler interface has one method to implement:

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

Finally, the last authentication class we need to cover is the Callback interface. This is a tagging interface for which several default implementations are provided, including the NameCallback and PasswordCallback used in an earlier example. A LoginModule uses a Callback to request information required by the authentication mechanism. LoginModules pass an array of Callbacks directly to the CallbackHandler.handle method during the authentication's login phase. If a callbackhandler does not understand how to use a Callback object passed into the handle method, it throws an UnsupportedCallbackException to abort the login call.



JBoss 4. 0(c) The Official Guide
JBoss 4.0 - The Official Guide
ISBN: B003D7JU58
EAN: N/A
Year: 2006
Pages: 137

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net