package javax.security.auth.login;
import gnu.java.security.action.GetSecurityPropertyAction;
import java.security.AccessController;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.spi.LoginModule;
public class LoginContext
{
private static final String OTHER = "other";
private final String name;
private final CallbackHandler cbHandler;
private final Subject subject;
private final AppConfigurationEntry[] entries;
private final LoginModule[] modules;
private final Map sharedState;
public LoginContext (final String name) throws LoginException
{
this (name, new Subject(), defaultHandler());
}
public LoginContext (final String name, final CallbackHandler cbHandler)
throws LoginException
{
this (name, new Subject(), cbHandler);
}
public LoginContext (final String name, final Subject subject)
throws LoginException
{
this (name, subject, defaultHandler());
}
public LoginContext (final String name, final Subject subject,
final CallbackHandler cbHandler)
throws LoginException
{
Configuration config = Configuration.getConfig();
AppConfigurationEntry[] entries = config.getAppConfigurationEntry (name);
if (entries == null)
entries = config.getAppConfigurationEntry (OTHER);
if (entries == null)
throw new LoginException ("no configured modules for application "
+ name);
this.entries = entries;
modules = new LoginModule[entries.length];
sharedState = new HashMap();
for (int i = 0; i < entries.length; i++)
modules[i] = lookupModule (entries[i], subject, sharedState);
this.name = name;
this.subject = subject;
this.cbHandler = cbHandler;
}
public Subject getSubject()
{
return subject;
}
public void login() throws LoginException
{
boolean failure = false;
for (int i = 0; i < modules.length; i++)
{
try
{
boolean result = modules[i].login();
if (!result)
{
if (entries[i].getControlFlag() ==
AppConfigurationEntry.LoginModuleControlFlag.REQUISITE)
throw new LoginException ("REQUISITE module " + entries[i].getLoginModuleName()
+ " failed");
else if (entries[i].getControlFlag() ==
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED)
failure = true;
}
else
{
if (entries[i].getControlFlag() ==
AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT)
break;
}
}
catch (LoginException le)
{
if (entries[i].getControlFlag() !=
AppConfigurationEntry.LoginModuleControlFlag.REQUISITE)
continue;
for (int j = 0; j < modules.length; j++)
modules[i].abort();
throw le;
}
}
if (failure)
throw new LoginException ("not all REQUIRED modules succeeded");
for (int i = 0; i < modules.length; i++)
modules[i].commit();
}
public void logout() throws LoginException
{
for (int i = 0; i < modules.length; i++)
modules[i].logout();
}
private static CallbackHandler defaultHandler()
{
GetSecurityPropertyAction act =
new GetSecurityPropertyAction ("auth.login.defaultCallbackHandler");
String classname = (String) AccessController.doPrivileged (act);
if (classname != null)
{
try
{
return (CallbackHandler) Class.forName (classname).newInstance();
}
catch (ClassNotFoundException cnfe)
{
return null;
}
catch (ClassCastException cce)
{
return null;
}
catch (IllegalAccessException iae)
{
return null;
}
catch (InstantiationException ie)
{
return null;
}
}
return null;
}
private LoginModule lookupModule (AppConfigurationEntry entry,
Subject subject, Map sharedState)
throws LoginException
{
LoginModule module = null;
Exception cause = null;
try
{
module = (LoginModule) Class.forName (entry.getLoginModuleName()).newInstance();
}
catch (ClassNotFoundException cnfe)
{
cause = cnfe;
}
catch (ClassCastException cce)
{
cause = cce;
}
catch (IllegalAccessException iae)
{
cause = iae;
}
catch (InstantiationException ie)
{
cause = ie;
}
if (cause != null)
{
LoginException le = new LoginException ("could not load module "
+ entry.getLoginModuleName());
le.initCause (cause);
throw le;
}
module.initialize (subject, cbHandler, sharedState, entry.getOptions());
return module;
}
}