Custom Login Module: Errors with 3.2.4
cbuckley Jul 29, 2004 11:31 AMI have a custom login module that I have been using with 3.2.3 successfully. I am trying to move my applications to 3.2.4 and I am getting the following error when trying to authenticate.
09:22:30,885 DEBUG [TransAriaJaasLoginModule] %%%%%%% Initialize has been called %%%%%%%
09:22:30,885 DEBUG [TransAriaJaasLoginModule] %%%%%%% Using realm upstream.cutthroatcom.com and controller madison.upstream.cutthroatcom.com %%%%%%%
09:22:30,885 DEBUG [TransAriaJaasLoginModule] %%%%%%% Using role query select role, rolegroup from cci_role where principal=? %%%%%%%
09:22:30,885 DEBUG [TransAriaJaasLoginModule] %%% Let's try InfoGears %%%
09:22:30,885 DEBUG [TransAriaJaasLoginModule] %%% You're attempting to log in via InfoGears %%%
09:22:30,885 INFO [STDOUT] User name: demo
09:22:30,901 DEBUG [TransAriaJaas] Login failure
javax.security.auth.login.LoginException: java.lang.SecurityException: attempting to add an object which is not an instance of java.security.Principal to a Subject's Principal Set
at javax.security.auth.Subject$SecureSet.add(Subject.java:1072)
at org.jboss.security.auth.spi.AbstractServerLoginModule.commit(AbstractServerLoginModule.java:186)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:675)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:129)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:610)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:607)
at javax.security.auth.login.LoginContext.login(LoginContext.java:535)
at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:476)
at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:430)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:246)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:221)
at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.authenticate(JBossSecurityMgrRealm.java:337)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:229)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:446)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.jboss.web.tomcat.tc5.session.ClusteredSessionValve.invoke(ClusteredSessionValve.java:78)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:297)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:371)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:731)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:663)
at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:859)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:730)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:129)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:610)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:607)
at javax.security.auth.login.LoginContext.login(LoginContext.java:535)
at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:476)
at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:430)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:246)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:221)
at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.authenticate(JBossSecurityMgrRealm.java:337)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:229)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:446)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.jboss.web.tomcat.tc5.session.ClusteredSessionValve.invoke(ClusteredSessionValve.java:78)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:297)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:371)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:731)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:663)
at org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:859)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)
package intuinet.security.auth.spi; import intuinet.callback.TransAriaCallbackHandler; import java.security.Principal; import java.security.acl.Group; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.sql.DataSource; import org.jboss.security.SecurityAssociation; import org.jboss.security.SimpleGroup; import org.jboss.security.SimplePrincipal; import org.jboss.security.auth.spi.UsernamePasswordLoginModule; /** * @author cbuckley * */ public class TransAriaJaasLoginModule extends UsernamePasswordLoginModule { private Principal identity; private String dsJndiName; private String rolesQuery = "select role, rolegroup from cci_role where principal=?"; String username = null; String authType = null; /* * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map) */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map configOptions) { super.initialize(subject,callbackHandler,sharedState,configOptions); String realm = (String) configOptions.get("kbr5Realm"); String kdc = (String) configOptions.get("kbr5Kdc"); rolesQuery = (String) configOptions.get("rolesQuery"); dsJndiName = (String) configOptions.get("dsJndiName"); log.debug("%%%%%%% Initialize has been called %%%%%%%"); log.debug("%%%%%%% Using realm "+realm+" and controller "+kdc+" %%%%%%%"); log.debug("%%%%%%% Using role query "+rolesQuery+" %%%%%%%"); //Setting system variables.... java.util.Properties p = new java.util.Properties(System.getProperties()); p.setProperty("java.security.krb5.realm",realm ); p.setProperty("java.security.krb5.kdc", kdc); System.setProperties(p); } /* * @see org.jboss.security.auth.spi.AbstractServerLoginModule#getIdentity() */ protected Principal getIdentity() { return identity; } /** * */ protected Group[] getRoleSets() throws LoginException { Group [] roles = null; if(authType.equals("InfoGears")){ roles = setInfoGearsRoleSets(); }else if(authType.equals("Domain")){ roles = setUpstreamRoleSets(); } return roles; } /** * * @return * @throws LoginException */ protected Group[] setInfoGearsRoleSets() throws LoginException { Connection conn = null; HashMap setsMap = new HashMap(); PreparedStatement ps = null; super.log.debug("%%% Username is '"+ username+"' %%%"); super.log.debug("%%% DataSource is "+ dsJndiName +" %%%"); try{ InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(dsJndiName); conn = ds.getConnection(); // Get the users role names ps = conn.prepareStatement(rolesQuery); ps.setString(1, username); ResultSet rs = ps.executeQuery(); if( rs.next() == false ){ Group group = (Group) setsMap.get("Roles"); if( group == null ){ group = new SimpleGroup("Roles"); setsMap.put("Roles", group); } group.addMember(new SimplePrincipal("IntuinetUser")); } do { String name = rs.getString(1); String groupName = rs.getString(2); if( groupName == null || groupName.length() == 0 ) groupName = "Roles"; Group group = (Group) setsMap.get(groupName); if( group == null ){ group = new SimpleGroup(groupName); setsMap.put(groupName, group); group.addMember(new SimplePrincipal("IntuinetUser")); } group.addMember(new SimplePrincipal(name)); } while( rs.next() ); rs.close(); } catch(NamingException ex){ super.log.error("Naming failure", ex); throw new LoginException(ex.toString(true)); } catch(SQLException ex){ super.log.error("Role Query: "+rolesQuery); super.log.error("SQL failure", ex); throw new LoginException(ex.toString()); } finally { if( ps != null ){ try{ ps.close(); }catch(SQLException e){ super.log.error("General Exception"+e.getMessage()); } } if( conn != null ){ try{ conn.close(); }catch (Exception ex){ super.log.error("General Exception"+ex.getMessage()); } } } Group[] roleSets = new Group[setsMap.size()]; setsMap.values().toArray(roleSets); super.log.debug("%%% Roles size is (number of roles) "+roleSets.length+"%%%"); return roleSets; } /* * @see org.jboss.security.auth.spi.AbstractServerLoginModule#getRoleSets() */ protected Group[] setUpstreamRoleSets() throws LoginException { Connection conn = null; HashMap setsMap = new HashMap(); PreparedStatement ps = null; super.log.debug("%%% Username is '"+ username+"' %%%"); super.log.debug("%%% DataSource is "+ dsJndiName +" %%%"); try{ InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(dsJndiName); conn = ds.getConnection(); // Get the users role names ps = conn.prepareStatement(rolesQuery); ps.setString(1, username); ResultSet rs = ps.executeQuery(); if( rs.next() == false ) { super.log.debug("%%% We have nothing in the result set %%%"); if( getUnauthenticatedIdentity() == null ) throw new FailedLoginException("No matching username found in Roles"); /* We are running with an unauthenticatedIdentity so create an empty Roles set and return. */ Group group = (Group) setsMap.get("Roles"); if( group == null ){ group = new SimpleGroup("Roles"); setsMap.put("Roles", group); } group.addMember(new SimplePrincipal("IntuinetUser")); Group[] roleSets = new Group[setsMap.size()]; setsMap.values().toArray(roleSets); super.log.debug("%%% Roles size is (number of roles) "+roleSets.length+"%%%"); return roleSets; } do { String name = rs.getString(1); String groupName = rs.getString(2); if( groupName == null || groupName.length() == 0 ) groupName = "Roles"; Group group = (Group) setsMap.get(groupName); if( group == null ){ group = new SimpleGroup(groupName); setsMap.put(groupName, group); } group.addMember(new SimplePrincipal(name)); } while( rs.next() ); rs.close(); } catch(NamingException ex){ super.log.error("Naming failure", ex); throw new LoginException(ex.toString(true)); } catch(SQLException ex){ super.log.error("Role Query: "+rolesQuery); super.log.error("SQL failure", ex); throw new LoginException(ex.toString()); } finally { if( ps != null ){ try{ ps.close(); }catch(SQLException e){ super.log.error("General Exception"+e.getMessage()); } } if( conn != null ){ try{ conn.close(); }catch (Exception ex){ super.log.error("General Exception"+ex.getMessage()); } } } Group group = (Group) setsMap.get("Roles"); if( group == null ){ group = new SimpleGroup("Roles"); setsMap.put("Roles", group); } group.addMember(new SimplePrincipal("IntuinetUser")); Group[] roleSets = new Group[setsMap.size()]; setsMap.values().toArray(roleSets); super.log.debug("%%% Roles size is (number of roles) "+roleSets.length+"%%%"); return roleSets; } /* * @see javax.security.auth.spi.LoginModule#login() */ public boolean login() throws LoginException { super.loginOk = false; identity = SecurityAssociation.getPrincipal(); LoginContext lc = null; String [] info = getUsernameAndPassword(); //Now try the InfoGears database log.debug("%%% Let's try InfoGears %%%"); try { TransAriaCallbackHandler callback = new TransAriaCallbackHandler(info[0], info[1]); lc = new LoginContext("InfoGears", callback); } catch (LoginException le1) { log.debug("%%% Cannot create LoginContext. %%%" + le1.getMessage()); } catch (SecurityException se) { log.debug("%%% Cannot create LoginContext. Security Exception %%%" + se.getMessage()); } try { log.debug("%%% You're attempting to log in via InfoGears %%%"); username = getUsername(); authType = "InfoGears"; lc.login(); super.loginOk = true; } catch (LoginException le1) { super.log.error("InfoGears Errors: "+le1.getMessage()); //Try to attempt a Domain Controller login via the domain controller. try { boolean valid = false; //I don't want people to have to put @UP... in the username. TransAriaCallbackHandler callback = new TransAriaCallbackHandler(info[0]+"@UPSTREAM.CUTTHROATCOM.COM", info[1]); lc = new LoginContext("domain-contoller", callback); } catch (LoginException le) { log.debug("%%% Cannot create LoginContext. %%%" + le.getMessage()); } catch (SecurityException se) { log.debug("%%% Cannot create LoginContext. Security Exception %%%" + se.getMessage()); } try { log.debug("%%% You're attempting to log in via the Domain Controller %%%"); //The username in the roles table is the email address. username = getUsername()+"@transaria.com"; authType = "Domain"; lc.login(); super.loginOk = true; } catch (LoginException le) { log.debug("%%% Authentication Failed: No Keberos/InfoGears login information %%%"); log.debug(" " + le.getMessage()); throw new FailedLoginException("Password Incorrect/Password Required"); } } return true; } /* (non-Javadoc) * @see org.jboss.security.auth.spi.UsernamePasswordLoginModule#getUsersPassword() */ protected String getUsersPassword() throws LoginException { return null; } }