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