Custom Principal propagation
petka Sep 25, 2007 4:25 PMI have the following problem. My custom loggin module is logged successfuly, but when I call request.getUserPrincipal();from struts action it return me object of class SimplePrincipal not from my customPrincipal class. I expect request.getUserPrincipal() return me object ot type PetkaPrincipal.
Where is my mistake?
This is my code.
client auth.conf
srp-client { // Example client auth.conf for using the SRPLoginModule org.jboss.security.srp.jaas.SRPLoginModule required password-stacking="useFirstPass" principalClassName="org.jboss.security.SimplePrincipal" srpServerJndiName="SRPServerInterface" debug=true ; // jBoss LoginModule org.jboss.security.ClientLoginModule required password-stacking="useFirstPass" ; // Put your login modules that need jBoss here }; other { // jBoss LoginModule org.jboss.security.ClientLoginModule required ; // Put your login modules that need jBoss here }; // added by me petka { org.petka.security.login.LoginModule required unauthenticatedIdentity=nobody; };
server auth.conf
petka { org.petka.security.login.LoginModule required unauthenticatedIdentity=nobody; };
login-conf.xml
<application-policy name="petka"> <authentication> <login-module code="org.petka.security.login.LoginModule" flag="required"> <module-option name="managedConnectionFactoryName"> jboss.jca:service=LocalTxCM,name=PostgresDS </module-option> <!--module-option name="principalClass">org.petka.security.login.PetkaPrincipal</module-option--> <module-option name="dsJndiName">java:/PostgresDS</module-option> <module-option name="principalsQuery"> Select * from Users where username =? </module-option> <module-option name="rolesQuery"> Select role as "Roles",'' as "Group" from Users where username =? </module-option> </login-module> </authentication> </application-policy>
my custom login modle
package org.petka.security.login; import java.security.Principal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import javax.sql.DataSource; import javax.transaction.Transaction; import org.jboss.security.auth.spi.DatabaseServerLoginModule; import org.jboss.tm.TransactionDemarcationSupport; public class LoginModule extends DatabaseServerLoginModule { Long id; String username; String password; String firstName; String lastName; String eMail; Boolean sex; boolean active; PetkaPrincipal caller; @Override public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { super.initialize(subject, callbackHandler, sharedState, options); Object tmp = options.get("principalsQuery"); if (tmp != null) { this.principalsQuery = tmp.toString(); } } @Override public boolean login() throws LoginException { if (super.login()) { caller = new PetkaPrincipal(getUsername()); return true; } return false; } @Override public boolean logout() throws LoginException { return super.logout(); } @Override protected Principal createIdentity(String username) throws Exception { PetkaPrincipal principal = new PetkaPrincipal(username, password, firstName, lastName, id, eMail, sex, active); return principal; } @Override protected String getUsersPassword() throws LoginException { String username = getUsername(); String password = null; Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Transaction tx = null; if (suspendResume) { tx = TransactionDemarcationSupport.suspendAnyTransaction(); } try { InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(dsJndiName); conn = ds.getConnection(); // Get the password ps = conn.prepareStatement(this.principalsQuery); ps.setString(1, username); rs = ps.executeQuery(); if (rs.next()) { password = initializeModuleFromRS(rs); } if (password == null) { throw new FailedLoginException("No matching username found in Principals"); } } catch (NamingException ex) { throw new LoginException(ex.toString(true)); } catch (SQLException ex) { //log.error("Query failed", ex); throw new LoginException(ex.toString()); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { //log.error(e); } } if (ps != null) { try { ps.close(); } catch (SQLException e) { //log.error(e); } } if (conn != null) { try { conn.close(); } catch (SQLException ex) { //log.error(ex); } } if (suspendResume) { TransactionDemarcationSupport.resumeAnyTransaction(tx); } } return password; } private String initializeModuleFromRS(ResultSet rs) throws SQLException { id = rs.getLong("id"); username = rs.getString("username"); password = rs.getString("password"); password = convertRawPassword(password); firstName = rs.getString("firstName"); lastName = rs.getString("lastName"); eMail = rs.getString("Email"); sex = rs.getBoolean("sex"); active = rs.getBoolean("active"); return password; } @Override protected String[] getUsernameAndPassword() throws LoginException { String[] info = {null, null}; byte[] credentialByte; // prompt for a username and password if( callbackHandler == null ) { throw new LoginException("Error: no CallbackHandler available " + "to collect authentication information"); } NameCallback nc = new NameCallback("User name: ", "guest"); PasswordCallback pc = new PasswordCallback("Password: ", false); Callback[] callbacks = {nc, pc}; String username = null; String password = null; try { callbackHandler.handle(callbacks); username = nc.getName(); char[] tmpPassword = pc.getPassword(); if( tmpPassword != null ) { int l = tmpPassword.length; credentialByte = new byte[l]; for(int i=0;i<l;i++){ credentialByte = (byte)tmpPassword; } pc.clearPassword(); password = new String(credentialByte, "utf8"); } } catch(java.io.IOException ioe) { throw new LoginException(ioe.toString()); } catch(UnsupportedCallbackException uce) { throw new LoginException("CallbackHandler does not support: " + uce.getCallback()); } info[0] = username; info[1] = password; return info; } }
my cstom principal
package org.petka.security.login; import org.jboss.security.SimplePrincipal; public class PetkaPrincipal extends SimplePrincipal{ /** * Auto generated serial version ID */ private static final long serialVersionUID = 4941550409387519691L; Long id; String username; String password; String firstName; String lastName; String eMail; Boolean sex; boolean active; public PetkaPrincipal(String username){ super(username); this.username = username; } public PetkaPrincipal(String username, String password, String firstName, String lastName, Long id, String eMail, Boolean sex, boolean active) { super(username); this.password = password; this.firstName = firstName; this.lastName = lastName; this.id = id; this.eMail = eMail; this.sex = sex; this.active = active; } public PetkaPrincipal(PetkaPrincipal principal){ super(principal.getUsername()); this.password = principal.getPassword(); this.firstName = principal.getFirstName(); this.lastName = principal.getLastName(); this.id = principal.getId(); this.eMail = principal.getEMail(); this.sex = principal.getSex(); this.active = principal.isActive(); } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } public String getEMail() { return eMail; } public void setEMail(String mail) { eMail = mail; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Boolean getSex() { return sex; } public void setSex(Boolean sex) { this.sex = sex; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
I package login module and principal to jar and putted to ..server/default/lib
My system is:
Ubunru 7.04, java jdk1.5.0_12, jboss-4.2.1.GA