2 Replies Latest reply on Oct 25, 2007 5:06 AM by Alexander Hartner

    Custom Principal propagation

    Petka Newbie

      I 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