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