Index: java/org/apache/catalina/Realm.java =================================================================== --- java/org/apache/catalina/Realm.java (revision 1765945) +++ java/org/apache/catalina/Realm.java (working copy) @@ -231,4 +231,13 @@ * @return principal roles */ public String[] getRoles(Principal principal); + + + /** + * Return the availability of the realm for authentication. + * @return true if the realm is able to perform authentication + */ + default public boolean isAvailable() { + return true; + } } Index: java/org/apache/catalina/realm/CombinedRealm.java =================================================================== --- java/org/apache/catalina/realm/CombinedRealm.java (revision 1765945) +++ java/org/apache/catalina/realm/CombinedRealm.java (working copy) @@ -418,4 +418,15 @@ throw uoe; } + + @Override + public boolean isAvailable() { + for (Realm realm : realms) { + if (!realm.isAvailable()) { + return false; + } + } + return true; + } + } Index: java/org/apache/catalina/realm/JNDIRealm.java =================================================================== --- java/org/apache/catalina/realm/JNDIRealm.java (revision 1765945) +++ java/org/apache/catalina/realm/JNDIRealm.java (working copy) @@ -2379,6 +2379,12 @@ } + @Override + public boolean isAvailable() { + // Simple best effort check + return (context != null); + } + private DirContext createDirContext(Hashtable env) throws NamingException { if (useStartTls) { return createTlsDirContext(env); Index: java/org/apache/catalina/realm/DataSourceRealm.java =================================================================== --- java/org/apache/catalina/realm/DataSourceRealm.java (revision 1765945) +++ java/org/apache/catalina/realm/DataSourceRealm.java (working copy) @@ -107,6 +107,12 @@ protected String userTable = null; + /** + * Last connection attempt. + */ + private volatile boolean connectionSuccess = true; + + // ------------------------------------------------------------- Properties @@ -270,6 +276,11 @@ } + @Override + public boolean isAvailable() { + return connectionSuccess; + } + // -------------------------------------------------------- Package Methods @@ -378,8 +389,11 @@ context = getServer().getGlobalNamingContext(); } DataSource dataSource = (DataSource)context.lookup(dataSourceName); - return dataSource.getConnection(); + Connection connection = dataSource.getConnection(); + connectionSuccess = true; + return connection; } catch (Exception e) { + connectionSuccess = false; // Log the problem for posterity containerLog.error(sm.getString("dataSourceRealm.exception"), e); } Index: java/org/apache/catalina/realm/LockOutRealm.java =================================================================== --- java/org/apache/catalina/realm/LockOutRealm.java (revision 1765945) +++ java/org/apache/catalina/realm/LockOutRealm.java (working copy) @@ -212,7 +212,7 @@ */ private Principal filterLockedAccounts(String username, Principal authenticatedUser) { // Register all failed authentications - if (authenticatedUser == null) { + if (authenticatedUser == null && isAvailable()) { registerAuthFailure(username); } Index: java/org/apache/catalina/realm/JDBCRealm.java =================================================================== --- java/org/apache/catalina/realm/JDBCRealm.java (revision 1765945) +++ java/org/apache/catalina/realm/JDBCRealm.java (working copy) @@ -414,6 +414,12 @@ } + @Override + public boolean isAvailable() { + return (dbConnection != null); + } + + /** * Close the specified database connection. *