users@glassfish.java.net

Relationship between custom realm and default jdbcRealm

From: <glassfish_at_javadesktop.org>
Date: Wed, 09 Jun 2010 09:12:13 PDT

Hi,

Witch is the relationship between a custom realm and the default jdbcRealm?

I have developed a custom LoginModule as follows,

public class MyLoginModule implements LoginModule {

        private boolean commitSucceeded = false;
        private boolean succeeded = false;
           
        private User user;
        private Set<Role> roles = new HashSet<Role>();
          
        protected Subject subject;
        protected CallbackHandler callbackHandler;
        
        protected Map<String, ?> sharedState = new HashMap<String, Object>();
        
    private String username;
    private char[] password;
    
    private UsertableController usertableController;
    private GrouptableController grouptableController;

    /**
     * Clears out password state.
     */
    public void clearPassword() {
        if (password != null) {
            for (int i = 0; i < password.length; i++)
                password[i] = ' ';
            password = null;
        }
    }

        public Subject getSubject() {
                return subject;
        }

        public void setSubject(Subject subject) {
                this.subject = subject;
        }

        public CallbackHandler getCallbackHandler() {
                return callbackHandler;
        }

        public void setCallbackHandler(CallbackHandler callbackHandler) {
                this.callbackHandler = callbackHandler;
        }
        
        @SuppressWarnings("unchecked")
        public void initialize(Subject subject, CallbackHandler callbackHandler,
                        Map<String, ?> sharedState, Map<String, ?> options) {
                // TODO Auto-generated method stub
                this.subject = subject;
                this.callbackHandler = callbackHandler;
                this.sharedState = sharedState;
                HashSet<Object> hs = new HashSet(this.subject.getPrivateCredentials());
                Iterator<Object> it = hs.iterator();
                while(it.hasNext()){
                        PasswordCredential pc = (PasswordCredential)it.next();
                        this.username = pc.getUser();
                        this.password = pc.getPassword().toCharArray();
                }
        }
        
        public boolean login() throws LoginException {
                // TODO Auto-generated method stub
                try {
                        getUsernamePassword();
                } catch (UnsupportedCallbackException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                validaUsuario();
                
                String[] groups = new String[roles.size()];
                
                Iterator<Role> it = roles.iterator();
                int i = 0;
                while (it.hasNext()) {
                        groups[i] = it.next().getName();
                        i++;
                }
                CTJDBCLoginModuleUser login = new CTJDBCLoginModuleUser("dukesbankRealm", username, groups);
                //sharedState.put("javax.security.auth.principal", user);
                //sharedState.put("javax.security.auth.roles", roles);

                return true;
        }
        
        public boolean commit() throws LoginException {
                // TODO Auto-generated method stub
                if (user != null && !subject.getPrincipals().contains(user)) {
                        subject.getPrincipals().add(user);
                }
                if (roles != null) {
                        Iterator<Role> it = roles.iterator();
                        while (it.hasNext()) {
                                Role role = new Role(it.next().getName());
                                if (!subject.getPrincipals().contains(role)) {
                                        subject.getPrincipals().add(role);
                                }
                        }
                }
                commitSucceeded = true;
                return true;
        }
        
        public boolean logout() throws LoginException {
                // TODO Auto-generated method stub
                subject.getPrincipals().removeAll(roles);
                subject.getPrincipals().remove(user);
                return true;
        }

        public boolean abort() throws LoginException {
                // TODO Auto-generated method stub
                if (!succeeded) {
                        return false;
                } else if (succeeded && !commitSucceeded) {
                        succeeded = false;
                } else {
                        succeeded = false;
                        logout();
                }

                this.subject = null;
                this.callbackHandler = null;
                this.sharedState = null;
                this.roles = new HashSet<Role>();

                return succeeded;
        }

        private void validaUsuario() throws LoginException {
                Usertable myUser = null;
                String pass = null;
                try {
                        usertableController = (UsertableController)((new InitialContext()).lookup("java:global/dukesbank/dukesbank-ejb/UsertableControllerBean"));
                        myUser = usertableController.getUser(username);
                        if (myUser != null) {
                                pass = myUser.getPassword();
                        } else {
                                succeeded = false;
                                throw new LoginException("User not found.");
                        }
                } catch (Exception e) {
                        succeeded = false;
                        throw new LoginException(e.getClass().getName() + ": " + e.getMessage());
                }
                
                if (passInformado.equals(pass)) {
                        user = new User(loginInformado);
                        recuperaRoles(myUser);
                        Iterator<Role> it = roles.iterator();
                        Set<String> userRoles = new HashSet<String>();
                        while(it.hasNext()){
                                String userRole = ((Role)it.next()).getName();
                                userRoles.add(userRole);
                        }
                        user.setRoles(userRoles);
                        return;
                } else {
                        throw new LoginException("Invalid password.");
                }
        }

        /**
         * Recupera as roles no banco
         */
        public void recuperaRoles(Usertable user) throws LoginException {
                try {
                        String username = user.getUsername();
                        grouptableController = (GrouptableController)((new InitialContext()).lookup("java:global/dukesbank/dukesbank-ejb/GrouptableControllerBean"));
                        List<Grouptable> list = grouptableController.findGroupByName(username);
                        Iterator<Grouptable> it = list.iterator();
                        while (it.hasNext()) {
                                Grouptable role = it.next();
                                if(role.getId().getUsername().equals(username)){
                                        roles.add(new Role(role.getId().getGroupname()));
                                }
                        }
                } catch (Exception e) {
                        succeeded = false;
                        throw new LoginException("Error while retrieving roles: " + e.getClass().getName() + ": " + e.getMessage());
                }
        }

        /**
         * User.
         */
        protected String loginInformado;
        /**
         * Password.
         */
        protected String passInformado;

        protected void getUsernamePassword() throws LoginException, UnsupportedCallbackException {
                if (callbackHandler == null)
                        throw new LoginException("Error: no CallbackHandler available to garner authentication information from the user");

                Callback[] callbacks = new Callback[2];
                callbacks[0] = new NameCallback(username);
                callbacks[1] = new PasswordCallback(password.toString(), false);
                for (Callback callback : callbacks) {
                    if (callback instanceof NameCallback) {
                        ((NameCallback) callback).setName(username);
                        continue;
                    } else if (callback instanceof PasswordCallback) {
                        ((PasswordCallback) callback).setPassword((password != null)
                                ? password : null);
                        continue;
                    }
                }
                //callbackHandler.handle(callbacks);
                loginInformado = ((NameCallback) callbacks[0]).getName();
                char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
                passInformado = new String(tmpPassword);
                ((PasswordCallback) callbacks[1]).clearPassword();
        }
}


and the GF v3 login.conf leaves as follows,

fileRealm {
        com.sun.enterprise.security.auth.login.FileLoginModule required;
};

ldapRealm {
        com.sun.enterprise.security.auth.login.LDAPLoginModule required;
};

solarisRealm {
        com.sun.enterprise.security.auth.login.SolarisLoginModule required;
};

jdbcRealm {
        com.sun.enterprise.security.auth.login.JDBCLoginModule required;
};

dukesbankRealm {
        com.sun.enterprise.security.auth.login.MyLoginModule required
        username="200"
        password="javaee"
        ;
};

jdbcDigestRealm {
       com.sun.enterprise.security.auth.login.JDBCDigestLoginModule required;
};

My surprise is that it works. In fact no other user and pass but the defined in the tables are valid login user and pass. The custom LoginModule validates those username and password. If I comment de default jdbcRealm in the login.conf the app does not let me login.

Will you give me an explanation?

Regards,
Jose
[Message sent by forum member 'josealvarezdelara']

http://forums.java.net/jive/thread.jspa?messageID=473596