Back Forum Reply New

Spring and JAAS (on Tomcat)

Hello,

I am trying to use Spring to instantiate an authentication bean that I would like to use in my implementation of the LoginModule (JAAS) on Tomcat 5.5.17. To do this I have done the following...

In $TOMCAT_HOME/common/classes, have put the following files (see attachments)...

beanRefFactory.xml
spring.xml
log4j.xml

In my web application, I have added the following to the web.xml file (also attached)...

lt;context-paramgt;
lt;param-namegt;contextConfigLocationlt;/param-namegt;
lt;param-valuegt;/WEB-INF/applicationContext.xmllt;/param-valuegt;
lt;/context-paramgt;

lt;listenergt;
lt;listener-classgt;
org..web.context.ContextLoaderListe  ner
lt;/listener-classgt;
lt;/listenergt;

lt;listenergt;
lt;listener-classgt;
org..web.util.Log4jConfigListener
lt;/listener-classgt;
lt;/listenergt;

The applicationContext.xml file is attached. The spring.xml file referred to in the applicationContext.xml file is a duplicate of the above spring.xml file and is put in the WEB-INF directory.

Upon starting Tomcat, I get a fairly nasty stack trace which is also attached (stacktrace.txt - messages about circular references - BeanCurrentlyInCreationException). Also, I am running Tomcat as a service and it does not seem to shut down, I get the following...
  INFO: Failed shutdown of Apache Portable Runtime

The log4j.xml (the same copy) also exists in WEB-INF.

Does anyone know what's going on?

Thanks,

Matthew

Could what I describe above be a conflict between the beanRefFactory.xml and applicationContext.xml?

I use the formar in Tomcat's common directories which are global to the Tomcat server instance and all the web applications. However, the applicationContext.xml file is specific to the web application (mywebapp).

It seems though the JAAS stuff needs to be configured at the server level (in server.xml) therefore my implementation of the JAAS LoginModule needs to live in the server classpath. Since this uses Spring, then the Spring stuff has to be defined at the server level too (so I have put the beanRefFactory.xml file in $TOMCAT_HOME/common/classes). I have a .jar file containing all the relevant classes in $TOMCAT_HOME/common/lib (along with spring-1.2.8.jar).

From what I see in the stacktrace the constructor of one of your classes throws an exception. Moreover, your setup doesn't seem right as your are trying to mix the server classpath with the webapp classpath.
If you have to use LoginModule inside the server then place only that class inside the server class. If it relies on classes from your webapp then you'll have to reconsider the approach since the webapp classloader will always be a child of the server clsasloader, that is, classes from the server lib cannot load classes/use from the webapp - only the other way around.
Give acegi a try - it provides a lot of security features and does not require specific application container configuration (you don't have to edit server.xml).

Thanks for the reply.

I have no need for the classes associated with the server class loader to be known to those assocated with the web application class loader (or vice versa).

I am of the understanding that classes in server/lib are invisible to those in WEB-INF/lib (and vice versa). I have therefore put the spring jar (and its dependencies) in server/lib and then put all the same spring related jars in WEB-INF/lib. I would have thought this would enable Spring for use by the LoginModule and the web application. Is this not so?

Thanks,

Matthew

If you put the libraries inside the server lib they will be visible to the webapps so you don't have to duplicate them. The problem (from what I see in the stacktrace) comes from circular dependencies - are you trying to bootstrap the same application context from the LoginModule?
Is there some relationship between the LoginModule and the webapp? (it shouldn't be).

From what I remember about JAAS, you can if you need to with Tomcat just put everything in your web app.  Can you get it working that way, as a sanity check?

Everything in the one app has two drawbacks: 1) you can't share the JAAS configuration across multiple applications; 2) it doesn't work in other platforms (e.g. Websphere), so if Tomcat isn't your only target it will break at some point.  So it might be worth persevering.

The other thing I remember about JAAS is that it is an SPI, and if you want to have the API jar in your server, and the implementation API in your web app, then it should work.  That way your LoginModule would be defined only in the web app (in a child class loader) with all its dependencies except javax.security.auth in the same class loader.  That should solve your start up problem.

If the API is in the parent classloader, to make the configuration shareable, the configuration has to be as well - we have to force the parent classloader to load it somehow.  I'm not sure how you do that with Tomcat (Websphere is easy - you just add a new javax.security.auth.login.Configuration in the server using the admin GUI).

This problem was fixed as a result of information in this thread.
¥
Back Forum Reply New