Problems Accessing Realm (JBossSecurityMgrRealm) from Tomcat
jofree Jun 19, 2006 1:16 PMI'm working on a custom Single Sign On solution and am having problems with JBossSecurityMgrRealm not working from within my Tomcat Valve and I can't figure out why. Here are the details:
I'm using JBoss AS 4.0.4GA.
I have the following code inside of a custom Tomcat Valve:
//Context context = request.getContext(); //Realm realm = context.getRealm(); Realm realm = this.getContainer().getRealm(); Principal newPrincipal = realm.authenticate(user, pass);
Both variations produce the same unexpected results (authentication always fails), I traced this through the JBoss code and found that the JBossSecurityMgrRealm class has a method getSecurityContext() which always returns null when called from within my valve.
private Context getSecurityContext()
{
Context securityCtx = null;
// Get the JBoss security manager from the ENC context
try
{
InitialContext iniCtx = new InitialContext();
securityCtx = (Context) iniCtx.lookup("java:comp/env/security");
}
catch (NamingException e)
{
// Apparently there is no security context?
}
return securityCtx;
}
The code in my custom Authenticator seems to work.
Realm realm = context.getRealm(); ... principal = realm.authenticate(username, password);
The only difference that I have been able to find is that the context variable from AuthenticatorBase is set in an overridden setContainer method from ValveBase, here is AuthenticatorBase.setContainer:
public void setContainer(Container container) {
if (!(container instanceof Context))
throw new IllegalArgumentException
(sm.getString("authenticator.notContext"));
super.setContainer(container);
this.context = (Context) container;
}
When I try to mimic this behavior in my custom valve, I find that my container is not an instance of Context. The only other thing that I am doing is using the configClass attribute of the host entry in server.xml to install my custom authenticator.
<Host name="localhost" autoDeploy="false" deployOnStartup="false" deployXML="false" configClass="com.acxiom.web.sso.config.ContextConfig"> <Valve className="com.acxiom.web.sso.SingleSignOnValve" />
public class ContextConfig extends org.apache.catalina.startup.ContextConfig {
public ContextConfig() {
super();
try {
Map authMap = this.getAuthenticators();
if (authMap.size() > 0) {
customAuthenticators = authMap;
}
}
catch (Exception e) {
//TODO Error Checking
}
}
private Map getAuthenticators() throws Exception {
Map cmap = new HashMap();
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
Authenticator form = (Authenticator)tcl.loadClass("com.acxiom.web.sso.FormAuthenticator").newInstance();
cmap.put("FORM", form);
return cmap;
}
}
I don't want to change any of the behavior of the Realm, only the Valve and Authenticators. Any help figuring this out would be appreciated, sorry for the verbose message, but I wanted to make sure all the relevant information was included.
Thanks,
Josh Freeman