Fields Summary |
---|
protected String | connectionNameThe connection username to use when trying to connect to the database. |
protected String | connectionPasswordThe connection URL to use when trying to connect to the database. |
protected String | connectionURLThe connection URL to use when trying to connect to the database. |
protected Connection | dbConnectionThe connection to the database. |
protected Driver | driverInstance of the JDBC Driver class we use as a connection factory. |
protected String | driverNameThe JDBC driver to use. |
protected static final String | infoDescriptive information about this Realm implementation. |
protected static final String | nameDescriptive information about this Realm implementation. |
protected PreparedStatement | preparedCredentialsThe PreparedStatement to use for authenticating users. |
protected PreparedStatement | preparedRolesThe PreparedStatement to use for identifying the roles for
a specified user. |
protected String | roleNameColThe column in the user role table that names a role |
protected static final org.apache.catalina.util.StringManager | smThe string manager for this package. |
protected String | userCredColThe column in the user table that holds the user's credintials |
protected String | userNameColThe column in the user table that holds the user's name |
protected String | userRoleTableThe table that holds the relation between user's and roles |
protected String | userTableThe table that holds user data. |
Methods Summary |
---|
public synchronized java.security.Principal | authenticate(java.lang.String username, java.lang.String credentials)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.
// 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;
|
public synchronized java.security.Principal | authenticate(java.sql.Connection dbConnection, java.lang.String username, java.lang.String credentials)Return the Principal associated with the specified username and
credentials, if there is one; otherwise return null .
// 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));
|
protected void | close(java.sql.Connection dbConnection)Close the specified database connection.
// 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;
}
|
protected java.sql.PreparedStatement | credentials(java.sql.Connection dbConnection, java.lang.String username)Return a PreparedStatement configured to perform the SELECT required
to retrieve user credentials for the specified username.
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);
|
public java.lang.String | getConnectionName()Return the username to use to connect to the database.
// ------------------------------------------------------------- Properties
return connectionName;
|
public java.lang.String | getConnectionPassword()Return the password to use to connect to the database.
return connectionPassword;
|
public java.lang.String | getConnectionURL()Return the URL to use to connect to the database.
return connectionURL;
|
public java.lang.String | getDriverName()Return the JDBC driver that will be used.
return driverName;
|
protected java.lang.String | getName()Return a short name for this Realm implementation.
return (name);
|
protected synchronized java.lang.String | getPassword(java.lang.String username)Return the password associated with the given principal's user name.
// 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);
|
protected java.security.Principal | getPrincipal(java.lang.String username)Return the Principal associated with the given user name.
return (new GenericPrincipal(this,
username,
getPassword(username),
getRoles(username)));
|
public java.lang.String | getRoleNameCol()Return the column in the user role table that names a role.
return roleNameCol;
|
protected java.util.ArrayList | getRoles(java.lang.String username)Return the roles associated with the gven user name.
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);
|
public java.lang.String | getUserCredCol()Return the column in the user table that holds the user's credentials.
return userCredCol;
|
public java.lang.String | getUserNameCol()Return the column in the user table that holds the user's name.
return userNameCol;
|
public java.lang.String | getUserRoleTable()Return the table that holds the relation between user's and roles.
return userRoleTable;
|
public java.lang.String | getUserTable()Return the table that holds user data..
return userTable;
|
protected java.sql.Connection | open()Open (if necessary) and return a database connection for use by
this Realm.
// 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);
|
protected void | release(java.sql.Connection dbConnection)Release our use of this connection so that it can be recycled.
; // NO-OP since we are not pooling anything
|
protected synchronized java.sql.PreparedStatement | roles(java.sql.Connection dbConnection, java.lang.String username)Return a PreparedStatement configured to perform the SELECT required
to retrieve user roles for the specified username.
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);
|
public void | setConnectionName(java.lang.String connectionName)Set the username to use to connect to the database.
this.connectionName = connectionName;
|
public void | setConnectionPassword(java.lang.String connectionPassword)Set the password to use to connect to the database.
this.connectionPassword = connectionPassword;
|
public void | setConnectionURL(java.lang.String connectionURL)Set the URL to use to connect to the database.
this.connectionURL = connectionURL;
|
public void | setDriverName(java.lang.String driverName)Set the JDBC driver that will be used.
this.driverName = driverName;
|
public void | setRoleNameCol(java.lang.String roleNameCol)Set the column in the user role table that names a role.
this.roleNameCol = roleNameCol;
|
public void | setUserCredCol(java.lang.String userCredCol)Set the column in the user table that holds the user's credentials.
this.userCredCol = userCredCol;
|
public void | setUserNameCol(java.lang.String userNameCol)Set the column in the user table that holds the user's name.
this.userNameCol = userNameCol;
|
public void | setUserRoleTable(java.lang.String userRoleTable)Set the table that holds the relation between user's and roles.
this.userRoleTable = userRoleTable;
|
public void | setUserTable(java.lang.String userTable)Set the table that holds user data.
this.userTable = userTable;
|
public void | start()Prepare for active use of the public methods of this Component.
// 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);
}
|
public void | stop()Gracefully shut down active use of the public methods of this Component.
// Perform normal superclass finalization
super.stop();
// Close any open DB connection
close(this.dbConnection);
|