1 Reply Latest reply on Jul 29, 2004 6:56 PM by Scott Stark

    Custom Login Module: Errors with 3.2.4

    Chris Buckley Newbie

      I 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;
       }
      
      
      }