| Method from org.apache.catalina.realm.JDBCRealm Detail: |
public synchronized Principal authenticate(String username,
String credentials) {
// Number of tries is the numebr of attempts to connect to the database
// during this login attempt (if we need to open the database)
// This needs rewritten wuth better pooling support, the existing code
// needs signature changes since the Prepared statements needs cached
// with the connections.
// The code below will try twice if there is a SQLException so the
// connection may try to be opened again. On normal conditions (including
// invalid login - the above is only used once.
int numberOfTries = 2;
while (numberOfTries >0) {
try {
// Ensure that we have an open database connection
open();
// Acquire a Principal object for this user
Principal principal = authenticate(dbConnection,
username, credentials);
// Return the Principal (if any)
return (principal);
} catch (SQLException e) {
// Log the problem for posterity
containerLog.error(sm.getString("jdbcRealm.exception"), e);
// Close the connection so that it gets reopened next time
if (dbConnection != null)
close(dbConnection);
}
numberOfTries--;
}
// Worst case scenario
return null;
}
Return the Principal associated with the specified username and
credentials, if there is one; otherwise return null.
If there are any errors with the JDBC connection, executing
the query or anything we return null (don't authenticate). This
event is also logged, and the connection will be closed so that
a subsequent request will automatically re-open it. |
public synchronized Principal authenticate(Connection dbConnection,
String username,
String credentials) {
// No user - can't possibly authenticate
if (username == null) {
return (null);
}
// Look up the user's credentials
String dbCredentials = getPassword(username);
// Validate the user's credentials
boolean validated = false;
if (hasMessageDigest()) {
// Hex hashes should be compared case-insensitive
validated = (digest(credentials).equalsIgnoreCase(dbCredentials));
} else {
validated = (digest(credentials).equals(dbCredentials));
}
if (validated) {
if (containerLog.isTraceEnabled())
containerLog.trace(sm.getString("jdbcRealm.authenticateSuccess",
username));
} else {
if (containerLog.isTraceEnabled())
containerLog.trace(sm.getString("jdbcRealm.authenticateFailure",
username));
return (null);
}
ArrayList< String > roles = getRoles(username);
// Create and return a suitable Principal for this user
return (new GenericPrincipal(this, username, credentials, roles));
}
Return the Principal associated with the specified username and
credentials, if there is one; otherwise return null. |
protected void close(Connection dbConnection) {
// Do nothing if the database connection is already closed
if (dbConnection == null)
return;
// Close our prepared statements (if any)
try {
preparedCredentials.close();
} catch (Throwable f) {
;
}
this.preparedCredentials = null;
try {
preparedRoles.close();
} catch (Throwable f) {
;
}
this.preparedRoles = null;
// Close this database connection, and log any errors
try {
dbConnection.close();
} catch (SQLException e) {
containerLog.warn(sm.getString("jdbcRealm.close"), e); // Just log it here
} finally {
this.dbConnection = null;
}
}
Close the specified database connection. |
protected PreparedStatement credentials(Connection dbConnection,
String username) throws SQLException {
if (preparedCredentials == null) {
StringBuffer sb = new StringBuffer("SELECT ");
sb.append(userCredCol);
sb.append(" FROM ");
sb.append(userTable);
sb.append(" WHERE ");
sb.append(userNameCol);
sb.append(" = ?");
if(containerLog.isDebugEnabled()) {
containerLog.debug("credentials query: " + sb.toString());
}
preparedCredentials =
dbConnection.prepareStatement(sb.toString());
}
if (username == null) {
preparedCredentials.setNull(1,java.sql.Types.VARCHAR);
} else {
preparedCredentials.setString(1, username);
}
return (preparedCredentials);
}
Return a PreparedStatement configured to perform the SELECT required
to retrieve user credentials for the specified username. |
public String getConnectionName() {
// ------------------------------------------------------------- Properties
return connectionName;
}
Return the username to use to connect to the database. |
public String getConnectionPassword() {
return connectionPassword;
}
Return the password to use to connect to the database. |
public String getConnectionURL() {
return connectionURL;
}
Return the URL to use to connect to the database. |
public String getDriverName() {
return driverName;
}
Return the JDBC driver that will be used. |
protected String getName() {
return (name);
}
Return a short name for this Realm implementation. |
protected synchronized String getPassword(String username) {
// Look up the user's credentials
String dbCredentials = null;
PreparedStatement stmt = null;
ResultSet rs = null;
// Number of tries is the numebr of attempts to connect to the database
// during this login attempt (if we need to open the database)
// This needs rewritten wuth better pooling support, the existing code
// needs signature changes since the Prepared statements needs cached
// with the connections.
// The code below will try twice if there is a SQLException so the
// connection may try to be opened again. On normal conditions (including
// invalid login - the above is only used once.
int numberOfTries = 2;
while (numberOfTries >0) {
try {
// Ensure that we have an open database connection
open();
try {
stmt = credentials(dbConnection, username);
rs = stmt.executeQuery();
if (rs.next()) {
dbCredentials = rs.getString(1);
}
rs.close();
rs = null;
if (dbCredentials == null) {
return (null);
}
dbCredentials = dbCredentials.trim();
return dbCredentials;
} finally {
if (rs!=null) {
try {
rs.close();
} catch(SQLException e) {
containerLog.warn(sm.getString("jdbcRealm.abnormalCloseResultSet"));
}
}
dbConnection.commit();
}
} catch (SQLException e) {
// Log the problem for posterity
containerLog.error(sm.getString("jdbcRealm.exception"), e);
// Close the connection so that it gets reopened next time
if (dbConnection != null)
close(dbConnection);
}
numberOfTries--;
}
return (null);
}
Return the password associated with the given principal's user name. |
protected Principal getPrincipal(String username) {
return (new GenericPrincipal(this,
username,
getPassword(username),
getRoles(username)));
}
Return the Principal associated with the given user name. |
public String getRoleNameCol() {
return roleNameCol;
}
Return the column in the user role table that names a role. |
protected ArrayList getRoles(String username) {
PreparedStatement stmt = null;
ResultSet rs = null;
// Number of tries is the numebr of attempts to connect to the database
// during this login attempt (if we need to open the database)
// This needs rewritten wuth better pooling support, the existing code
// needs signature changes since the Prepared statements needs cached
// with the connections.
// The code below will try twice if there is a SQLException so the
// connection may try to be opened again. On normal conditions (including
// invalid login - the above is only used once.
int numberOfTries = 2;
while (numberOfTries >0) {
try {
// Ensure that we have an open database connection
open();
try {
// Accumulate the user's roles
ArrayList< String > roleList = new ArrayList< String >();
stmt = roles(dbConnection, username);
rs = stmt.executeQuery();
while (rs.next()) {
String role = rs.getString(1);
if (null!=role) {
roleList.add(role.trim());
}
}
rs.close();
rs = null;
return (roleList);
} finally {
if (rs!=null) {
try {
rs.close();
} catch(SQLException e) {
containerLog.warn(sm.getString("jdbcRealm.abnormalCloseResultSet"));
}
}
dbConnection.commit();
}
} catch (SQLException e) {
// Log the problem for posterity
containerLog.error(sm.getString("jdbcRealm.exception"), e);
// Close the connection so that it gets reopened next time
if (dbConnection != null)
close(dbConnection);
}
numberOfTries--;
}
return (null);
}
Return the roles associated with the gven user name. |
public String getUserCredCol() {
return userCredCol;
}
Return the column in the user table that holds the user's credentials. |
public String getUserNameCol() {
return userNameCol;
}
Return the column in the user table that holds the user's name. |
public String getUserRoleTable() {
return userRoleTable;
}
Return the table that holds the relation between user's and roles. |
public String getUserTable() {
return userTable;
}
Return the table that holds user data.. |
protected Connection open() throws SQLException {
// Do nothing if there is a database connection already open
if (dbConnection != null)
return (dbConnection);
// Instantiate our database driver if necessary
if (driver == null) {
try {
Class clazz = Class.forName(driverName);
driver = (Driver) clazz.newInstance();
} catch (Throwable e) {
throw new SQLException(e.getMessage());
}
}
// Open a new connection
Properties props = new Properties();
if (connectionName != null)
props.put("user", connectionName);
if (connectionPassword != null)
props.put("password", connectionPassword);
dbConnection = driver.connect(connectionURL, props);
dbConnection.setAutoCommit(false);
return (dbConnection);
}
Open (if necessary) and return a database connection for use by
this Realm. |
protected void release(Connection dbConnection) {
; // NO-OP since we are not pooling anything
}
Release our use of this connection so that it can be recycled. |
protected synchronized PreparedStatement roles(Connection dbConnection,
String username) throws SQLException {
if (preparedRoles == null) {
StringBuffer sb = new StringBuffer("SELECT ");
sb.append(roleNameCol);
sb.append(" FROM ");
sb.append(userRoleTable);
sb.append(" WHERE ");
sb.append(userNameCol);
sb.append(" = ?");
preparedRoles =
dbConnection.prepareStatement(sb.toString());
}
preparedRoles.setString(1, username);
return (preparedRoles);
}
Return a PreparedStatement configured to perform the SELECT required
to retrieve user roles for the specified username. |
public void setConnectionName(String connectionName) {
this.connectionName = connectionName;
}
Set the username to use to connect to the database. |
public void setConnectionPassword(String connectionPassword) {
this.connectionPassword = connectionPassword;
}
Set the password to use to connect to the database. |
public void setConnectionURL(String connectionURL) {
this.connectionURL = connectionURL;
}
Set the URL to use to connect to the database. |
public void setDriverName(String driverName) {
this.driverName = driverName;
}
Set the JDBC driver that will be used. |
public void setRoleNameCol(String roleNameCol) {
this.roleNameCol = roleNameCol;
}
Set the column in the user role table that names a role. |
public void setUserCredCol(String userCredCol) {
this.userCredCol = userCredCol;
}
Set the column in the user table that holds the user's credentials. |
public void setUserNameCol(String userNameCol) {
this.userNameCol = userNameCol;
}
Set the column in the user table that holds the user's name. |
public void setUserRoleTable(String userRoleTable) {
this.userRoleTable = userRoleTable;
}
Set the table that holds the relation between user's and roles. |
public void setUserTable(String userTable) {
this.userTable = userTable;
}
Set the table that holds user data. |
public void start() throws LifecycleException {
// Perform normal superclass initialization
super.start();
// Validate that we can open our connection - but let tomcat
// startup in case the database is temporarily unavailable
try {
open();
} catch (SQLException e) {
containerLog.error(sm.getString("jdbcRealm.open"), e);
}
}
Prepare for active use of the public methods of this Component. |
public void stop() throws LifecycleException {
// Perform normal superclass finalization
super.stop();
// Close any open DB connection
close(this.dbConnection);
}
Gracefully shut down active use of the public methods of this Component. |