[Solved] Waffle SSO on JBoss 6 (ClassCastException)

Apr 27, 2011 at 4:27 PM

I'm trying to create a SSO solution for our web apps in JBoss 4.2.2.

My solution so far are mostly copy/paste snippets from the tutorials but the log says that it works when i run it on Tomcat. So i tried the project on JBoss 4.2.2.

Again, i get logged in according to the log, but after the NegotiateAuthenticator sets the principal i'm getting a ClassCastException from JBoss' SecurityAssociationValve.

Obviously i'm not really sure if I have the correct approach so any pointers are welcome.

Or if anyone know how to get it running on JBoss 6 i'm also interested.





Excerpt from SecurityAssociationValve.java:

if (caller == null || (caller instanceof JBossGenericPrincipal) == false) {
   // Look to the session for the active caller security context
   if (session != null) {
      principal = (JBossGenericPrincipal) session.getPrincipal(); // Line 143
} else {
   // Use the request principal as the caller identity
   principal = (JBossGenericPrincipal) caller;


<?xml version="1.0" encoding="utf-8"?>
  <Valve className="waffle.apache.NegotiateAuthenticator" principalFormat="fqn" roleFormat="both" allowGuestLogin="false" />
  <Realm className="org.apache.catalina.realm.JAASRealm" appName="AuthRealm" userClassNames="waffle.jaas.UserPrincipal" roleClassNames="waffle.jaas.RolePrincipal" useContextClassLoader="false" debug="true" />

<application-policy name="AuthRealm">
    <login-module flag="requisite" code="waffle.jaas.WindowsLoginModule" />


 java.lang.ClassCastException: waffle.apache.GenericWindowsPrincipal cannot be cast to org.jboss.web.tomcat.security.JBossGenericPrincipal

	at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:143)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:524)
	at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
	at java.lang.Thread.run(Unknown Source)
Apr 29, 2011 at 2:01 PM

The exception comes from the simple reason that JAASRealm doesn't exist in JBoss.

To get it to work you have to:

Remove the realm definition from context.xml.

Edit the Waffle source and replace Response with HttpServletResponse on all authenticators and build Waffle against the bundled libs in JBoss.

When the user authenticates with the NegotiateAuthenticator all LoginModules are bypassed. Anyone have any idea of how to stop this behavior?


Apr 29, 2011 at 5:13 PM

What do your login modules do?

IMHO the best way is to use the filter vs. the authentication valves. Valves are vendor-specific.

Apr 29, 2011 at 6:17 PM

I'm kind of new at this 'Valve'-thing so please correct me if i'm wrong.

Thanks, i could move all my login logic to a Valve and then just use login modules as backup if the NegotiateAuthenticator failes?

I need to translate the username according to a database after a successful authentication so i need to modify the NegotiateAuthenticator cause it (AuthenticatorBase) doesn't chain on a successful authentication.

May 2, 2011 at 3:20 PM

I think you can separate those two pieces instead of modifying Waffle code. Let Waffle do its thing and authenticate. It will yield a Principal object in the session. A subsequent filter or valve can do more work with the authenticated user (such as look him up in a DB and yield a 401 if he's not authorized or wrap the principle object into another principle object that yields a different user id (same thing as what waffle does)).

May 3, 2011 at 6:58 AM

Thanks, I think I'll go for the Valve solution.

Jun 7, 2011 at 7:19 AM

I solved this exactly as dblock said.

But JBoss 6 is built on some strange version of Catalina that breaks backward compatibility on AuthenticatorBase, with the authenticate method that is changed from:

boolean authenticate(Request request, Response response, LoginConfig loginConfig)


boolean authenticate(Request request, HttpServletResponse response, LoginConfig loginConfig)

Read more about this at: http://community.jboss.org/message/544960?tstart=0


This forced me to modify the Waffle source anyway...