Fixed issue #360, used a DB connection pool instead of long lasting Drivers connections
This commit is contained in:
@@ -16,15 +16,20 @@
|
||||
|
||||
package io.moquette.spi.impl.security;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import io.moquette.BrokerConstants;
|
||||
import io.moquette.server.config.IConfig;
|
||||
import io.moquette.spi.security.IAuthenticator;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.sql.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Load user credentials from a SQL database. sql driver must be provided at runtime
|
||||
@@ -34,14 +39,14 @@ public class DBAuthenticator implements IAuthenticator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DBAuthenticator.class);
|
||||
|
||||
private final MessageDigest messageDigest;
|
||||
private final PreparedStatement preparedStatement;
|
||||
private HikariDataSource dataSource;
|
||||
private String sqlQuery;
|
||||
|
||||
public DBAuthenticator(IConfig conf) {
|
||||
this(
|
||||
conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_DRIVER, ""),
|
||||
conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_URL, ""),
|
||||
conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_QUERY, ""),
|
||||
conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_DIGEST, ""));
|
||||
this(conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_DRIVER, ""),
|
||||
conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_URL, ""),
|
||||
conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_QUERY, ""),
|
||||
conf.getProperty(BrokerConstants.DB_AUTHENTICATOR_DIGEST, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,18 +62,12 @@ public class DBAuthenticator implements IAuthenticator {
|
||||
* : password encoding algorithm : "MD5", "SHA-1", "SHA-256"
|
||||
*/
|
||||
public DBAuthenticator(String driver, String jdbcUrl, String sqlQuery, String digestMethod) {
|
||||
this.sqlQuery = sqlQuery;
|
||||
this.dataSource = new HikariDataSource();
|
||||
this.dataSource.setJdbcUrl(jdbcUrl);
|
||||
|
||||
try {
|
||||
Class.forName(driver);
|
||||
final Connection connection = DriverManager.getConnection(jdbcUrl);
|
||||
this.messageDigest = MessageDigest.getInstance(digestMethod);
|
||||
this.preparedStatement = connection.prepareStatement(sqlQuery);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
LOG.error(String.format("Can't find driver %s", driver), cnfe);
|
||||
throw new RuntimeException(cnfe);
|
||||
} catch (SQLException sqle) {
|
||||
LOG.error(String.format("Can't connect to %s", jdbcUrl), sqle);
|
||||
throw new RuntimeException(sqle);
|
||||
} catch (NoSuchAlgorithmException nsaex) {
|
||||
LOG.error(String.format("Can't find %s for password encoding", digestMethod), nsaex);
|
||||
throw new RuntimeException(nsaex);
|
||||
@@ -82,28 +81,40 @@ public class DBAuthenticator implements IAuthenticator {
|
||||
LOG.info("username or password was null");
|
||||
return false;
|
||||
}
|
||||
ResultSet r = null;
|
||||
|
||||
ResultSet resultSet = null;
|
||||
PreparedStatement preparedStatement = null;
|
||||
Connection conn = null;
|
||||
try {
|
||||
this.preparedStatement.setString(1, username);
|
||||
r = this.preparedStatement.executeQuery();
|
||||
if (r.next()) {
|
||||
final String foundPwq = r.getString(1);
|
||||
conn = this.dataSource.getConnection();
|
||||
|
||||
preparedStatement = conn.prepareStatement(this.sqlQuery);
|
||||
preparedStatement.setString(1, username);
|
||||
resultSet = preparedStatement.executeQuery();
|
||||
if (resultSet.next()) {
|
||||
final String foundPwq = resultSet.getString(1);
|
||||
messageDigest.update(password);
|
||||
byte[] digest = messageDigest.digest();
|
||||
String encodedPasswd = new String(Hex.encodeHex(digest));
|
||||
return foundPwq.equals(encodedPasswd);
|
||||
}
|
||||
r.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SQLException sqlex) {
|
||||
LOG.error("Error quering DB for username: {}", username, sqlex);
|
||||
} finally {
|
||||
try {
|
||||
if (resultSet != null) {
|
||||
resultSet.close();
|
||||
}
|
||||
if (preparedStatement != null) {
|
||||
preparedStatement.close();
|
||||
}
|
||||
if (conn != null) {
|
||||
conn.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LOG.error("Error releasing connection to the datasource", username, e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
this.preparedStatement.close();
|
||||
this.preparedStatement.getConnection().close();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user