com.opass.security.SaltAwareJdbcRealm.java Source code

Java tutorial

Introduction

Here is the source code for com.opass.security.SaltAwareJdbcRealm.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.opass.security;

/**
 *
 * @author agung
 */

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.util.JdbcUtils;
import org.apache.shiro.util.SimpleByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This realm has all {@link JdbcRealm} capabilities. It also supports  as datasource source and 
 * can add salt to passwords.
 */
public class SaltAwareJdbcRealm extends JdbcRealm {

    private static final Logger log = LoggerFactory.getLogger(SaltAwareJdbcRealm.class);

    protected String DataSourceName;

    public SaltAwareJdbcRealm() {
    }

    public String getDataSourceName() {
        return DataSourceName;
    }

    public void setDataSourceName(String DataSourceName) {
        this.DataSourceName = DataSourceName;
        this.dataSource = getDataSourceFrom(DataSourceName);
    }

    private DataSource getDataSourceFrom(String DataSourceName) {
        try {
            InitialContext ic = new InitialContext();
            return (DataSource) ic.lookup(DataSourceName);
        } catch (NamingException e) {
            log.error(" error while retrieving " + DataSourceName, e);
            throw new AuthorizationException(e);
        }
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //identify account to log to
        UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
        String username = userPassToken.getUsername();

        if (username == null) {
            log.debug("Username is null.");
            return null;
        }

        // read password hash and salt from db 
        PasswdSalt passwdSalt = getPasswordForUser(username);

        if (passwdSalt == null) {
            log.debug("No account found for user [" + username + "]");
            return null;
        }

        // return salted credentials
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, passwdSalt.password, getName());
        info.setCredentialsSalt(new SimpleByteSource(passwdSalt.salt));

        return info;
    }

    private PasswdSalt getPasswordForUser(String username) {
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            statement = conn.prepareStatement(authenticationQuery);
            statement.setString(1, username);

            resultSet = statement.executeQuery();

            boolean hasAccount = resultSet.next();
            if (!hasAccount)
                return null;

            String salt = null;
            String password = resultSet.getString(1);
            if (resultSet.getMetaData().getColumnCount() > 1)
                salt = resultSet.getString(2);

            if (resultSet.next()) {
                throw new AuthenticationException(
                        "More than one user row found for user [" + username + "]. Usernames must be unique.");
            }

            return new PasswdSalt(password, salt);
        } catch (SQLException e) {
            final String message = "There was a SQL error while authenticating user [" + username + "]";
            if (log.isErrorEnabled()) {
                log.error(message, e);
            }
            throw new AuthenticationException(message, e);

        } finally {
            JdbcUtils.closeResultSet(resultSet);
            JdbcUtils.closeStatement(statement);
            JdbcUtils.closeConnection(conn);
        }
    }

}

class PasswdSalt {

    public String password;
    public String salt;

    public PasswdSalt(String password, String salt) {
        super();
        this.password = password;
        this.salt = salt;
    }

}