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