jaas - LoginContext & Configuration Subclass

There appears to be a bug in the JAAS api involved in sub-classing the Configuration class. By default LoginContext uses the default implementation of Configuration (ConfigFile) to load modules and parameters. Each login module is then initalized when the login method of LoginContext is called. When using the default Configuration class, each instance of LoginContext results in a unique instance of each LoginModule.

When the Configuration class is extended, the LoginContext class behaves differently. Rather than each new instance of LoginContext resulting in a new instance of LoginModule, only one instance of LoginModule is ever instantiated. The initalize method of LoginModule is only ever called once, therefore the same instance of CallbackHanlder is executed resulting in the same data every time.

Is there something going on here, or are we doing something wrong in the Configuration subclass? Configuration subclass included below:

import javax.security.auth.login.Configuration;

import javax.security.auth.login.AppConfigurationEntry;

import java.util.ArrayList;

import java.util.StringTokenizer;

import java.util.HashMap;

public class AuthenticationConfiguration extends Configuration

{

private static ArrayList appConfigurationList = new ArrayList();

public AuthenticationConfiguration()

{

}

/**

* Interface method requiring us to return all the LoginModules we

* know about.

*/

public AppConfigurationEntry[] getAppConfigurationEntry( String applicationName )

{

AppConfigurationEntry[] ace = new AppConfigurationEntry[appConfigurationList.size()];

for (int i=0;i < appConfigurationList.size();i++)

{

ace = (AppConfigurationEntry)appConfigurationList.get(i);

}

return ace;

}

/**

* Interface method that requires us to reload the configuration.

* This method is defined but there is no underluing implementation.

*/

public void refresh()

{

// Right now this is a load once scheme and we will not implement the

// refresh method

}

/**

* Adds a new LoginModule entry from the configuration process

*/

public static boolean addAppConfigurationEntry ( String flag, String module, String options )

{

// REMOVED FOR BREVITY

}

}

[2421 byte] By [ servzone] at [2007-9-26 17:40:19]
# 1

I encoutered this problem too. I agree with you,

this looks like a bug in LoginContext.

After looking at the way they implemented LoginContext,

I was able to work around this by making sure the

getAppConfigurationEntry() method always return

brand new AppConfigurationEntry objects. The LoginContext uses these AppConfigurationEntry

objects and sets their 'module' attributes to the LoginModule used during login().

So the 2nd time around, if you return the same

AppConfigurationEntry object, its 'module' attribute is

already set by the first call to login(). LoginContext

will then reuse the same module and not re-initializing

the handler.

The following code is the culprit in LoginContext's

invoke() method:

if (moduleStack.module != null) {

methods = moduleStack.module.getClass().getMethods();

} else {

// instantiate the LoginModule

Class c = Class.forName

(moduleStack.getLoginModuleName(),

true,

contextClassLoader);

Constructor constructor = c.getConstructor(PARAMS);

Object[] args = { };

// allow any object to be a LoginModule

// as long as it conforms to the interface

moduleStack.module = constructor.newInstance(args);

methods = moduleStack.module.getClass().getMethods();

// call the LoginModule's initialize method

for (mIndex = 0; mIndex < methods.length; mIndex++) {

if (methods[mIndex].getName().equals(INIT_METHOD))

break;

}

Object[] initArgs = {subject,

callbackHandler,

state,

moduleStack.getOptions() };

// invoke the LoginModule initialize method

methods[mIndex].invoke(moduleStack.module, initArgs);

}

gstjio at 2007-7-2 23:01:00 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 2

I don't think it is a bug cause if you read the code of ConfigFile, the getAppConfigurationEntry method returns each time new AppConfigurationEntry objects

Also, have you tried to write your own Configuration file loader ? Cause I am trying to do so and after reading the source code of ConfigFile I still have some questions. Do they consider the override possibility ? I ask that because if the allowSystemProperty is set, it loads that file and anyway will load the login.config.url.n files. My understanding of the override parameter (-Djava.security.auth.login.config==login_module_config_file) is to only use that file and not load the config files defined by login.config.url.n=path_to_file

Jerome

jbaumgarten at 2007-7-2 23:01:00 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 3

Hi,

I am trying to implement the similar structure, that is to subclass Configuration file.

But where exactly can I specify this AuthenticationConfiguration so that when I say

new LoginContext("TestApp"), it can get its configuratioin info from this subclass.

I am using JDK1.3

Any help is highly appreciated.

Thanks in advance

Lavanya

lavanya_ at 2007-7-2 23:01:00 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 4
I am having the same problem (LoginModule reuse) using Oracle's app server (9iAS)...it specifies where the config file sits, so I am not dealing with a Configuration class, although i'm guessing that oracle is. Anything new on this subject?
cmarkiewicz at 2007-7-2 23:01:00 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 5

Let me add some more detail...

I have a client (jsp page) which instantiates a CallbackHandler, cbh, which contains authentication info from the Request...I then instantiate LoginContext with cbh and the appropriate name. My custom LoginModule validates the info against LDAP.

So, I start my Servlet Engine (I'm using Oracle9iAS, but it looks like this might be a Java issue and not an Oracle issue). I hit the jsp page, everything is cool. I hit the jsp page again with different credentials...only it still uses the first credentials. I added some logging and found out that the initialization() method of my LoginModule is only called once. After that, the same instance is reused so it never grabs new info.

The second post in this thread indicates that it is an issue between LoginContext and the Configuration class (in my case, the Config class is not mine...I'm guessing it's a proprietary Oracle thing).

Anyway, does anyone have ideas on how to get around this? The "All That JAAS" article specifically states that:

"LoginContext calls this method <initialize()> at the beginning of every call to its login() method. "

http://www.javaworld.com/javaworld/jw-09-2002/jw-0913-jaas-p3.html

I greatly appreciate any help.

Chris

cmarkiewicz at 2007-7-2 23:01:00 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 6
I implemented the fix suggested in the above thread and everything works as promised. So the error in my case in on Oracle's side (Oracle 9iAS v9.0.2...jdk 1.3).
cmarkiewicz at 2007-7-2 23:01:00 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 7
cmarkiewicz I am also tryin to deploy in Oracle 9i. I am new JAAS and oracle does not provide much help. Where is the configuration file where you put all the LoginModule configuration. If you could help me that would be great.
joshdmoore at 2007-7-2 23:01:01 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 8

Inspecting the code in jaas 1_0_01 (typically used with JDK 1.3) and JDK 1.4.2_02 (which includes JAAS), this bug seems to have been quietly fixed sometime between them.

In the LoginContext implementation in 1_0_01, the implementation does not clone the AppConfigurationEntry objects returned and writes to the "module" field of each entry when loaded; if you happen to return a reference to an AppConfigurationEntry[] that you returned previously (e.g. a static previously initialized), then this results in a bug that causes "initialize" to be called on the LoginModule only once ever.

The implementation in Java 1.4.2_02 fixes this by cloning each AppConfigurationEntry when the LoginContext is created.

To workaround this in jaas 1_0_01, you need to make sure your Configuration subclass always returns a new instance of each AppConfigurationEntry object when "AppConfigurationEntry[] getAppConfigurationEntry(String name)" is called.

agangolli at 2007-7-2 23:01:01 > top of Java-index,Security,Other Security APIs, Tools, and Issues...