Package com.evasion.sam.jaas

Source Code of com.evasion.sam.jaas.EvasionLoginModule

package com.evasion.sam.jaas;

import com.evasion.sam.PasswordEncoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
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.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.sql.DataSource;

/**
* Module d'authentification JAAS.
* @author sebastien
*/
public class EvasionLoginModule implements LoginModule {

    /**
     * LOGGER.
     */
    private static final Logger LOGGER = Logger.getLogger(EvasionLoginModule.class.getName());
    private static final String PARAM_DATASOURCE_JNDI = "datasource-jndi";
    private static final String PARAM_DIGEST_ALGORITHM = "digest-algorithm";
    private static final String DEFAULT_DIGEST_ALGORITHM = "sha+salt";
    private static final String PARAM_USER_TABLE = "user-table";
    private static final String PARAM_USER_NAME_COLUMN = "user-name-column";
    private static final String PARAM_PASSWORD_COLUMN = "password-column";
    private static final String PARAM_ACTIVE_COLUMN = "active-column";
    private static final String PARAM_BLOCK_COLUMN = "block-column";
    private static final String PARAM_LAST_LOGIN_COLUMN = "last-login-column";
    private static final String PARAM_ROLE_REQUEST = "role-request";
    private static final String BLANK_VALUE_SQL = "\"\"";
    private static final String COMA ="\"";
    private StringBuilder userQuery = new StringBuilder();
    private StringBuilder roleQuery = new StringBuilder();
    private Subject subject;
    private String username = null;
    private String password = null;
    private Date lastLogin = null;
    private CallbackHandler callbackHandler;
    private boolean success = true;
    private DataSource ds = null;
    private Connection con = null;
    private PreparedStatement pr = null;

    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {

        this.subject = subject;
        this.callbackHandler = callbackHandler;
        LOGGER.info("Init Evasion Login Module");
        String dsJndi = (String) options.get(PARAM_DATASOURCE_JNDI);
        String userTable = (String) options.get(PARAM_USER_TABLE);
        String userNameColumn = (String) options.get(PARAM_USER_NAME_COLUMN);
        String passwordColumn = (String) options.get(PARAM_PASSWORD_COLUMN);
        String activeColumn = (String) options.get(PARAM_ACTIVE_COLUMN);
        String blockColumn = (String) options.get(PARAM_BLOCK_COLUMN);
        String lastLoginColumn = (String) options.get(PARAM_LAST_LOGIN_COLUMN);
        String roleRequest = (String) options.get(PARAM_ROLE_REQUEST);
        String digestAlgorithm = (String) options.get(PARAM_DIGEST_ALGORITHM);
        LOGGER.info("------- Properties ------------------");
        completePropertiesAndLog(PARAM_DATASOURCE_JNDI, dsJndi);
        completePropertiesAndLog(PARAM_USER_TABLE, userTable);
        completePropertiesAndLog(PARAM_USER_NAME_COLUMN, userNameColumn);
        completePropertiesAndLog(PARAM_PASSWORD_COLUMN, passwordColumn);
        completePropertiesAndLog(PARAM_ROLE_REQUEST, roleRequest);
        completePropertiesAndLogWhtihDefaultValue(PARAM_DIGEST_ALGORITHM, digestAlgorithm, DEFAULT_DIGEST_ALGORITHM);
        completePropertiesAndLogWhtihDefaultValue(PARAM_ACTIVE_COLUMN, activeColumn, BLANK_VALUE_SQL);
        completePropertiesAndLogWhtihDefaultValue(PARAM_BLOCK_COLUMN, blockColumn, BLANK_VALUE_SQL);
        completePropertiesAndLogWhtihDefaultValue(PARAM_LAST_LOGIN_COLUMN, lastLoginColumn, BLANK_VALUE_SQL);

        roleQuery.append(roleRequest);
        userQuery.append("SELECT ").append(passwordColumn).append(", ").append(activeColumn).append(", ").append(blockColumn).append(", ").append(lastLoginColumn).append(" FROM ").append(userTable).append(" WHERE ").append(userNameColumn).append("=");
        LOGGER.info("Login Module query : " + userQuery);
        JmsClient client;
        try {
            client = new JmsClient();
            ds = (DataSource) client.lookup(dsJndi);
        } catch (Exception ex) {
            LOGGER.log(Level.SEVERE, "erreur JNDI lookup ", ex);
        }
    }

    private void completePropertiesAndLog(String propertyName, String propertyValue) {
        LOGGER.info(propertyName + " : " + propertyValue);
        if (propertyValue == null || propertyValue.equals("")) {
            LOGGER.severe(propertyName + " can not be null");
        }
    }

    private void completePropertiesAndLogWhtihDefaultValue(String propertyName, String propertyValue, String defaultValue) {
        if (propertyValue == null || ("").equals(propertyValue)) {
            propertyValue = defaultValue;
        }
        completePropertiesAndLog(propertyName, propertyValue);
    }

    @Override
    public boolean login() throws LoginException {
        LOGGER.info("Start Login");
        traitementPWD();


        // Hardcoded user verification. Only users user1 and super with password=password are allowed.
        ResultSet rs = null;
        try {
            con = ds.getConnection();
            pr = con.prepareStatement(userQuery + COMA + username + COMA);
            rs = pr.executeQuery();
            rs.first();
            String dbPassword = rs.getString(1);
            lastLogin = rs.getDate(4);
            if (!dbPassword.equals(password)) {
                LOGGER.log(Level.SEVERE, "Login Failed for user " + username + "!!!");
                throw new LoginException("Login Failed for user " + username + "!!!");
            }
            LOGGER.fine("Login succes");
            return true;
        } catch (SQLException ex) {
            LOGGER.log(Level.SEVERE, "SQL exception on user database.", ex);
            throw new LoginException("SQL exception on user database.");
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException ex) {
                    LOGGER.log(Level.SEVERE, "ResultSet Exception ", ex);
                }
            }

            if (con != null) {
                try {
                    con.close();
                } catch (SQLException ex) {
                    LOGGER.log(Level.SEVERE, "SQL Exception ", ex);
                }
            }
        }


    }

    private boolean traitementPWD() throws LoginException {
        try {

            NameCallback nc = new NameCallback("UsrName");
            PasswordCallback pc = new PasswordCallback("Passwd", false);
            callbackHandler.handle(new Callback[]{nc, pc});
            username = nc.getName();
            char[] tmp = pc.getPassword();
            if (tmp != null) {
                password = new String(tmp);
            }
            if (password == null || password.isEmpty() || username == null || username.isEmpty()) {
                LOGGER.severe("User or password are null");
                throw new LoginException("Login Failed for user " + username + "!!!");
            }

            password = PasswordEncoder.encodePassword(username, password);
            pc.clearPassword();
        } catch (Exception ex) {
            success = false;
            LoginException le = new LoginException("Login Failed!!!");
            LOGGER.severe("Login Failed with username: " + username + " and password: xxxxxx");
            le.initCause(ex);
            throw le;
        }
        LOGGER.fine("Login with username: " + username + " and password: xxxxxxxxx");
        return true;
    }

    @Override
    public boolean commit() throws LoginException {
        LOGGER.fine("Commit");
        if (username != null && success) {
            EvasionPrincipal user = new EvasionPrincipal(username);
            user.setLastLogin(lastLogin);
            subject.getPrincipals().add(user);

            if (roleQuery.length() > 0) {
                ResultSet rs=null;
                try {
                    int index = roleQuery.indexOf("?");
                    roleQuery.deleteCharAt(index);
                    roleQuery.insert(index, COMA + username + COMA);
                    LOGGER.fine("Role QUery: " + roleQuery.toString());
                    con = ds.getConnection();
                    pr = con.prepareStatement(roleQuery.toString());
                    rs = pr.executeQuery();
                    final List<String> rolesResult = new ArrayList<String>();

                    while (rs.next()) {
                        rolesResult.add(rs.getString(1));
                    }

                    EvasionGroup roles = new EvasionGroup("Roles");
                    for (String role : rolesResult) {
                        roles.addMember(new EvasionPrincipal(role));
                    }


                    subject.getPrincipals().add(roles);

                } catch (SQLException ex) {
                    LOGGER.log(Level.SEVERE, "SQL exception on group request. ", ex);
                    throw new LoginException("SQL exception on user database. ");
                } finally {
                    if (rs != null) {
                        try {
                            rs.close();
                        } catch (SQLException ex) {
                            LOGGER.log(Level.SEVERE, "ResultSet Exception ", ex);
                        }
                    }
                    if (con != null) {
                        try {
                            con.close();
                        } catch (SQLException ex) {
                            LOGGER.log(Level.SEVERE, "SQL Exception ", ex);
                        }
                    }
                }
            }
            return true;
        }
        return true;
    }

    @Override
    public boolean abort() throws LoginException {
        try {
            username = null;
            password = null;
            return true;
        } finally {
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException ex) {
                    LOGGER.log(Level.SEVERE, "SQL Exception ", ex);
                }
            }
        }
    }

    @Override
    public boolean logout() throws LoginException {
        subject.getPrincipals().remove(new EvasionPrincipal(username));
        username = null;
        password = null;
        return true;
    }

    public class JmsClient {

        private Context ctx;

        public JmsClient() {
            Map properties = new HashMap(2);
            properties.put(Context.PROVIDER_URL, "iiop://127.0.0.1:3700");
            try {
                ctx = new InitialContext(new Hashtable(properties));
            } catch (NamingException ex) {
                LOGGER.log(Level.SEVERE, "JNDI Exception ", ex);
            }
        }

        public Object lookup(String name) {
            try {
                return ctx.lookup(name);
            } catch (NamingException ex) {
                LOGGER.log(Level.SEVERE, "JNDI lookup Exception ", ex);
            }
            return null;
        }
    }
}
TOP

Related Classes of com.evasion.sam.jaas.EvasionLoginModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.