JAAS: Java Authentication and Authorization Service

Subject:

 

/**
 * <p> A <code>Subject</code> represents a grouping of related information
 * for a single entity, such as a person.
 * Such information includes the Subject's identities as well as
 * its security-related attributes
 * (passwords and cryptographic keys, for example).
 *
 * <p> Subjects may potentially have multiple identities.
 * Each identity is represented as a <code>Principal</code>
 * within the <code>Subject</code>.  Principals simply bind names to a
 * <code>Subject</code>.  For example, a <code>Subject</code> that happens
 * to be a person, Alice, might have two Principals:
 * one which binds "Alice Bar", the name on her driver license,
 * to the <code>Subject</code>, and another which binds,
 * "999-99-9999", the number on her student identification card,
 * to the <code>Subject</code>.  Both Principals refer to the same
 * <code>Subject</code> even though each has a different name.
 *
 * <p> A <code>Subject</code> may also own security-related attributes,
 * which are referred to as credentials.
 * Sensitive credentials that require special protection, such as
 * private cryptographic keys, are stored within a private credential
 * <code>Set</code>.  Credentials intended to be shared, such as
 * public key certificates or Kerberos server tickets are stored
 * within a public credential <code>Set</code>.  Different permissions
 * are required to access and modify the different credential Sets.
 *
 * <p> To retrieve all the Principals associated with a <code>Subject</code>,
 * invoke the <code>getPrincipals</code> method.  To retrieve
 * all the public or private credentials belonging to a <code>Subject</code>,
 * invoke the <code>getPublicCredentials</code> method or
 * <code>getPrivateCredentials</code> method, respectively.
 * To modify the returned <code>Set</code> of Principals and credentials,
 * use the methods defined in the <code>Set</code> class.
 * For example:
 * <pre>
 *	Subject subject;
 *	Principal principal;
 *	Object credential;
 *
 *	// add a Principal and credential to the Subject
 *	subject.getPrincipals().add(principal);
 *	subject.getPublicCredentials().add(credential);
 * </pre>
 *
 * <p> This <code>Subject</code> class implements <code>Serializable</code>.
 * While the Principals associated with the <code>Subject</code> are serialized,
 * the credentials associated with the <code>Subject</code> are not.
 * Note that the <code>java.security.Principal</code> class
 * does not implement <code>Serializable</code>.  Therefore all concrete
 * <code>Principal</code> implementations associated with Subjects
 * must implement <code>Serializable</code>.
 *
 * @version 1.123, 05/05/04
 * @see java.security.Principal
 * @see java.security.DomainCombiner
 */

 

 

LoginModule:

 

/**
 * <p> <code>LoginModule</code> describes the interface
 * implemented by authentication technology providers.  LoginModules
 * are plugged in under applications to provide a particular type of
 * authentication.
 *
 * <p> While applications write to the <code>LoginContext</code> API,
 * authentication technology providers implement the
 * <code>LoginModule</code> interface.
 * A <code>Configuration</code> specifies the LoginModule(s)
 * to be used with a particular login application.  Therefore different
 * LoginModules can be plugged in under the application without
 * requiring any modifications to the application itself.
 *
 *...
*/
 

 

PasswordLoginModule.java:

 

package com.wgu.jaas;

import java.io.IOException;
import java.security.Principal;
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 PasswordLoginModule implements LoginModule {

	public static final String USER_NAME = "jaas";

	/*
	 * A <code>Subject</code> represents a grouping of related information for
	 * a single entity, such as a person. It present a entity who will
	 * manipulate the system.
	 */
	private Subject mySubject;

	private CallbackHandler myCallbackHandler;

	private String username;

	private char[] password;

	private boolean loginSucceeded = false;

	private boolean commitSucceeded = false;

	/*
	 * This interface 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.
	 * 
	 */
	private Principal myPrincipal;

	/**
	 * abort() will be called if overall login failed.
	 */
	public boolean abort() throws LoginException {
		return false;
	}

	/**
	 * This is called once the login successed.
	 */
	public boolean commit() throws LoginException {
		if (!this.loginSucceeded) {
			return false;
		}
		myPrincipal = new PrincipalImpl(username);

		// create a Principal and add it to Subject.
		if (!mySubject.getPrincipals().contains(myPrincipal)) {
			mySubject.getPrincipals().add(myPrincipal);
		}

		username = null;
		clearPassword();
		commitSucceeded = true;
		return true;
	}

	/**
	 * Initialize the LoginModule according to configuration.
	 */
	public void initialize(Subject subject, CallbackHandler callbackHandler,
			Map<String, ?> sharedState, Map<String, ?> options) {
		this.mySubject = subject;
		this.myCallbackHandler = callbackHandler;
		loginSucceeded = false;
		commitSucceeded = false;
		username = null;
		clearPassword();
	}

	private void clearPassword() {
		if (this.password == null) {
			return;
		}

		for (char c : password) {
			c = (char) ' ';
		}

		password = null;
	}

	/**
	 * Attempt to log a user in.
	 */
	public boolean login() throws LoginException {
		if (myCallbackHandler == null) {
			throw new LoginException("No CallbackHandler defined.");
		}

		/*
		 * Implementations of this interface are passed to a <code>CallbackHandler</code>,
		 * allowing underlying security services the ability to interact with a
		 * calling application to retrieve specific authentication data such as
		 * usernames and passwords, or to display certain information, such as
		 * error and warning messages.
		 */
		Callback[] callbacks = new Callback[2];
		callbacks[0] = new NameCallback("UserName");
		callbacks[1] = new PasswordCallback("Password", false);

		try {
			myCallbackHandler.handle(callbacks);
			username = ((NameCallback) callbacks[0]).getName();
			char[] tempPsw = ((PasswordCallback) callbacks[1]).getPassword();
			password = new char[tempPsw.length];
			System.arraycopy(tempPsw, 0, password, 0, tempPsw.length);
			((PasswordCallback) callbacks[1]).clearPassword();
		} catch (IOException e) {
			throw new LoginException(e.getMessage());
		} catch (UnsupportedCallbackException e) {
			throw new LoginException(e.getMessage());
		}

		// we can update this component to check user/psw against database.
		if (username.equals(USER_NAME) && password.length == USER_NAME.length()) {
			loginSucceeded = true;
			return true;
		} else {
			loginSucceeded = false;
			username = null;
			clearPassword();
			return false;
		}
	}

	/**
	 * Logout user. It will remove Principal from Subject.
	 */
	public boolean logout() throws LoginException {
		mySubject.getPrincipals().remove(myPrincipal);
		loginSucceeded = false;
		commitSucceeded = false;
		username = null;
		clearPassword();
		myPrincipal = null;
		return true;
	}

	public static void main(String[] args) {
		char[] a = { 'a', 'b', 'c' };
		char[] b = a;

		// a = null;

		for (char c : a) {
			c = (char) ' ';
		}

		for (char c : b) {
			System.out.println(c);
		}
	}
}
 

 

UserNamePasswordCallbackHandler.java:

 

/**
 * 
 */
package com.wgu.jaas;

import java.io.IOException;

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;

/**
 * @author wgu
 * 
 */
public class UserNamePasswordCallbackHandler implements CallbackHandler {

	String username;

	char[] password;

	public UserNamePasswordCallbackHandler(String username, char[] password) {
		this.username = username;
		this.password = password;
	}

	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
		for (Callback callback : callbacks) {
			if (callback instanceof NameCallback) {
				NameCallback nameCb = (NameCallback) callback;
				nameCb.setName(username);
			} else if (callback instanceof PasswordCallback) {
				PasswordCallback pswCb = (PasswordCallback) callback;
				pswCb.setPassword(password);
			}
		}
	}

}
 

 

PrincipalImpl.java:

 

/**
 * 
 */
package com.wgu.jaas;

import java.io.Serializable;
import java.security.Principal;

/**
 * @author Administrator
 * 
 */
public class PrincipalImpl implements Principal, Serializable {
	private String name;

	public PrincipalImpl(String name) {
		this.name = name;
	}

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

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final PrincipalImpl other = (PrincipalImpl) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	public String getName() {
		return name;
	}

	public String toString() {
		return getName();
	}
}

 

 

JAASTest.java:

 

/**
 * 
 */
package com.wgu.jaas;

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

/**
 * @author wgu
 * 
 */
public class JAASTest {
	/**
	 * We have to config "-Djava.security.auth.login.config=jaas.config" to
	 * specify configuration file.
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		LoginContext lc = new LoginContext("JAASSample",
				new UserNamePasswordCallbackHandler());
		try {
			lc.login();
		} catch (LoginException e) {
			// Authentication failed.
		}

		// Authentication successful, we can now continue.
		// We can use the returned Subject if we like.
		Subject sub = lc.getSubject();
		System.out.println(sub);
	}
}
 

 

 

jaas.config:

 

JAASSample {
	com.wgu.jaas.PasswordLoginModule required
        option1="I am option";
};
 

 

JAASPriveligedActionExample.java:

 

package com.wgu.jaas;

import java.security.PrivilegedAction;

public class JAASPriveligedActionExample implements PrivilegedAction {

	public Object run() {
		System.out.println("Secret text: "
				+ JAASAuthorizationExample.getSecretText());

		return null;
	}

}
 

 

JAASAuthorizationExample.java:

package com.wgu.jaas;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Principal;

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

public class JAASAuthorizationExample {
	private static final String NO_PRINCIPAL = "NO_PRINCIPAL";

	public static String getSecretText() {
		AccessControlContext context = AccessController.getContext();
		Subject sub2 = Subject.getSubject(context);
		if (sub2 == null) {
			return NO_PRINCIPAL;
		}

		for (Principal p : sub2.getPrincipals()) {
			if (p.getName().equals(PasswordLoginModule.USER_NAME)) {
				return "PRINCIPAL_OK";
			}
		}

		return NO_PRINCIPAL;
	}

	/**
	 * We have to config "-Djava.security.auth.login.config=jaas.config" to
	 * specify configuration file.
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		LoginContext lc = new LoginContext("JAASSample",
				new UserNamePasswordCallbackHandler());
		try {
			lc.login();
		} catch (LoginException e) {
			// Authentication failed.
		}

		// Authentication successful, we can now continue.
		// We can use the returned Subject if we like.
		Subject sub = lc.getSubject();
		/*
		 * Perform work as a particular <code>Subject</code>.
		 * 
		 */
		Subject.doAs(sub, new JAASPriveligedActionExample());
	}

}
 

 

你可能感兴趣的:(Authentication)