
org.nakedobjects.plugins.hibernate.authentication.DatabaseAuthenticator Maven / Gradle / Ivy
The newest version!
package org.nakedobjects.plugins.hibernate.authentication;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.DatabaseMetaData;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.SQLQuery;
import org.nakedobjects.metamodel.commons.ensure.Assert;
import org.nakedobjects.metamodel.commons.exceptions.NakedObjectException;
import org.nakedobjects.metamodel.config.NakedObjectConfiguration;
import org.nakedobjects.plugins.hibernate.objectstore.util.HibernateUtil;
import org.nakedobjects.runtime.authentication.AuthenticationRequest;
import org.nakedobjects.runtime.authentication.PasswordAuthenticationRequest;
import org.nakedobjects.runtime.authentication.standard.Authenticator;
import org.nakedobjects.runtime.context.NakedObjectsContext;
/**
* example properties for various database types:
*
* nakedobjects.component.authenticator.algorithm= MD5
*
* nakedobjects.component.authenticator.selectusersql.default = \
* select count(*) \
* from user u \
* where username = ? and password = ?
*
* nakedobjects.component.authenticator.selectrolessql.default = \
* select r.rolename as rr \
* from role r, user u, user_role ur \
* where r.id = ur.role and ur.user = u.id and u.username = ?
*
* nakedobjects.component.authenticator.selectusersql.hsqldb = \
* select count(*) \
* from user u \
* where username = ? and password = ?
*
* nakedobjects.component.authenticator.selectrolessql.hsqldb = \
* select r.rolename as rr \
* from role r, user u, user_role ur \
* where r.id = ur.role and ur.user = u.id \
* and u.username = ?
*
* nakedobjects.component.authenticator.selectusersql.mysql =
* select count(*) from `user` u \
* where `username` = ? and `password` = ?
*
* nakedobjects.component.authenticator.selectrolessql.mysql = \
* select r.`rolename` as rr \
* from `role` r, `user` u, `user_role` ur \
* where r.`id` = ur.`role` and ur.`user` = u.`id` and u.`username` = ?
*
* nakedobjects.component.authenticator.selectusersql.postgresql = \
* select count(*) \
* from "user" u \
* where "username" = ? and "password" = ?
*
* nakedobjects.component.authenticator.selectrolessql.postgresql = \
* select r."rolename" as rr \
* from "role" r, "user" u, "user_role" ur \
* where r."id" = ur."role" and ur."user" = u."id" and u."username" = ?
*
*/
public class DatabaseAuthenticator implements Authenticator {
private static final boolean FAILED_AUTHENTICATION = false;
private static MessageDigest messageDigest;
private static String ALGORITHM = "MD5";
private static final String NO_ALGORITHM = "none";
private static String SELECT_USER_SQL = "select count(*) from user u where username = ? and password = ?";
private static String SELECT_ROLES_SQL = "select r.rolename as rr from role r, user u, user_role ur where r.id = ur.role and ur.user = u.id and u.username = ?";
private static final String AUTH_CFG = "nakedobjects.component.authenticator.";
private static final String SELECT_USER_CFG = AUTH_CFG + "selectusersql.";
private static final String SELECT_ROLES_CFG = AUTH_CFG + "selectrolessql.";
private static final String DEFAULT_CFG = "default";
private static final String ALGORITHM_CFG = AUTH_CFG + "algorithm";
private static boolean initializedSQL;
private static boolean initializedAlgorithm;
private NakedObjectConfiguration configuration;
public DatabaseAuthenticator(NakedObjectConfiguration configuration) {
this.configuration = configuration;
}
private static String getDBType(final String dbURL) {
// would use regex but want to stay compatible with earlier java versions as far as possible
if (dbURL != null && dbURL.toLowerCase().startsWith("jdbc:")) {
final int indexOfFirstColon = dbURL.indexOf(":"); // must be ok
final int indexOfSecondColon = dbURL.indexOf(":", indexOfFirstColon + 1);
if (indexOfSecondColon > indexOfFirstColon) {
return dbURL.substring(indexOfFirstColon + 1, indexOfSecondColon).trim();
}
}
return DEFAULT_CFG;
}
private void justInTimeInitialiseSQL() {
if (!initializedSQL) {
try {
HibernateUtil.startTransaction();
final DatabaseMetaData dbm = HibernateUtil.getCurrentSession().connection().getMetaData();
HibernateUtil.commitTransaction();
final String databaseType = getDBType(dbm.getURL());
// first default to hard coded sql above, then from property .default, then from property
// .
SELECT_USER_SQL = NakedObjectsContext.getConfiguration()
.getString(SELECT_USER_CFG + DEFAULT_CFG, SELECT_USER_SQL);
SELECT_ROLES_SQL = configuration.getString(SELECT_ROLES_CFG + DEFAULT_CFG,
SELECT_ROLES_SQL);
SELECT_USER_SQL = NakedObjectsContext.getConfiguration().getString(SELECT_USER_CFG + databaseType,
SELECT_USER_SQL);
SELECT_ROLES_SQL = NakedObjectsContext.getConfiguration().getString(SELECT_ROLES_CFG + databaseType,
SELECT_ROLES_SQL);
} catch (final Exception e) {
HibernateUtil.rollbackTransaction();
throw new NakedObjectException(e);
}
initializedSQL = true;
}
}
private void justInTimeInitialiseAlgorithm() {
if (!initializedAlgorithm) {
try {
ALGORITHM = configuration.getString(ALGORITHM_CFG, ALGORITHM);
if (!ALGORITHM.equalsIgnoreCase(NO_ALGORITHM)) {
messageDigest = MessageDigest.getInstance(ALGORITHM);
}
} catch (final NoSuchAlgorithmException nsa) {
throw new NakedObjectException(nsa);
}
initializedAlgorithm = true;
}
}
private final void setRoles(final AuthenticationRequest request) {
try {
HibernateUtil.startTransaction();
final SQLQuery sq = HibernateUtil.getCurrentSession().createSQLQuery(SELECT_ROLES_SQL);
sq.setString(0, request.getName());
sq.addScalar("rr", Hibernate.STRING);
final List roles = sq.list();
HibernateUtil.commitTransaction();
request.setRoles(roles.toArray(new String[roles.size()]));
} catch (final Exception e) {
HibernateUtil.rollbackTransaction();
throw new NakedObjectException(e);
}
}
public String generateHash(final String key) {
justInTimeInitialiseAlgorithm();
if (ALGORITHM.equalsIgnoreCase(NO_ALGORITHM)) {
return key;
}
synchronized (messageDigest) {
messageDigest.reset();
messageDigest.update(key.getBytes());
final byte[] bytes = messageDigest.digest();
final StringBuffer buff = new StringBuffer();
for (int l = 0; l < bytes.length; l++) {
final String hx = Integer.toHexString(0xFF & bytes[l]);
// make sure the hex string is correct if 1 character
if (hx.length() == 1) {
buff.append("0");
}
buff.append(hx);
}
return buff.toString().trim();
}
}
private int count(final Object countValue) {
if (countValue == null) {
return 0;
}
if (countValue instanceof Number) {
return ((Number) countValue).intValue();
}
throw new NakedObjectException("Unexpected type");
}
public final boolean isValidUser(final AuthenticationRequest request) {
final PasswordAuthenticationRequest passwordRequest = (PasswordAuthenticationRequest) request;
final String username = passwordRequest.getName();
if (username == null || username.equals("")) {
return FAILED_AUTHENTICATION;
}
final String password = passwordRequest.getPassword();
Assert.assertNotNull(password);
try {
HibernateUtil.startTransaction();
final SQLQuery sq = HibernateUtil.getCurrentSession().createSQLQuery(SELECT_USER_SQL);
sq.setString(0, username);
sq.setString(1, generateHash(password));
final Object result = sq.uniqueResult();
HibernateUtil.commitTransaction();
return count(result) > 0;
} catch (final Exception e) {
HibernateUtil.rollbackTransaction();
}
return FAILED_AUTHENTICATION;
}
public final boolean isValid(final AuthenticationRequest request) {
justInTimeInitialiseSQL();
final boolean valid = isValidUser(request);
if (valid) {
setRoles(request);
}
return valid;
}
public final boolean canAuthenticate(final AuthenticationRequest request) {
return request instanceof PasswordAuthenticationRequest;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy