diff --git a/java/org/apache/catalina/mbeans/MBeanUtils.java b/java/org/apache/catalina/mbeans/MBeanUtils.java index 9a3ea4d..c8d1156 100644 --- a/java/org/apache/catalina/mbeans/MBeanUtils.java +++ b/java/org/apache/catalina/mbeans/MBeanUtils.java @@ -787,6 +787,7 @@ public class MBeanUtils { // The database itself ObjectName db = new ObjectName( "Users:type=UserDatabase,database=" + userDatabase); - mserver.unregisterMBean(db); + if( mserver.isRegistered(db) ) + mserver.unregisterMBean(db); } } diff --git a/java/org/apache/catalina/realm/UserDatabaseRealm.java b/java/org/apache/catalina/realm/UserDatabaseRealm.java index d89e43c..5b01a99 100644 --- a/java/org/apache/catalina/realm/UserDatabaseRealm.java +++ b/java/org/apache/catalina/realm/UserDatabaseRealm.java @@ -27,19 +27,19 @@ import java.util.List; import javax.naming.Context; import org.apache.catalina.Group; -import org.apache.catalina.LifecycleException; import org.apache.catalina.Role; import org.apache.catalina.User; import org.apache.catalina.UserDatabase; import org.apache.catalina.Wrapper; +import org.apache.naming.ContextBindings; import org.apache.tomcat.util.ExceptionUtils; /** *
Implementation of {@link org.apache.catalina.Realm} that is based on an implementation of
- * {@link UserDatabase} made available through the global JNDI resources
+ * {@link UserDatabase} made available through the JNDI resources
* configured for this instance of Catalina. Set the resourceName
- * parameter to the global JNDI resources name for the configured instance
+ * parameter to the JNDI resources name for the configured instance
* of UserDatabase
that we should consult.
UserDatabase
we will use to authenticate users
- * and identify associated roles.
- */
- protected UserDatabase database = null;
-
-
- /**
* Descriptive information about this Realm implementation.
*/
protected static final String name = "UserDatabaseRealm";
/**
- * The global JNDI name of the UserDatabase
resource
+ * The JNDI name of the UserDatabase
resource
* we will be utilizing.
*/
protected String resourceName = "UserDatabase";
+
+ /**
+ * Context local datasource.
+ */
+ protected boolean localDataSource = false;
// ------------------------------------------------------------- Properties
/**
- * Return the global JNDI name of the UserDatabase
resource
+ * Return the JNDI name of the UserDatabase
resource
* we will be using.
*/
public String getResourceName() {
@@ -88,7 +86,7 @@ public class UserDatabaseRealm
/**
- * Set the global JNDI name of the UserDatabase
resource
+ * Set the JNDI name of the UserDatabase
resource
* we will be using.
*
* @param resourceName The new global JNDI name
@@ -137,7 +135,7 @@ public class UserDatabaseRealm
return false;
}
User user = (User)principal;
- Role dbrole = database.findRole(role);
+ Role dbrole = getDatabase().findRole(role);
if(dbrole == null) {
return false;
}
@@ -174,7 +172,7 @@ public class UserDatabaseRealm
@Override
protected String getPassword(String username) {
- User user = database.findUser(username);
+ User user = getDatabase().findUser(username);
if (user == null) {
return null;
@@ -191,7 +189,7 @@ public class UserDatabaseRealm
@Override
protected Principal getPrincipal(String username) {
- User user = database.findUser(username);
+ User user = getDatabase().findUser(username);
if(user == null) {
return null;
}
@@ -218,52 +216,44 @@ public class UserDatabaseRealm
// ------------------------------------------------------ Lifecycle Methods
- /**
- * Prepare for the beginning of active use of the public methods of this
- * component and implement the requirements of
- * {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
- *
- * @exception LifecycleException if this component detects a fatal error
- * that prevents this component from being used
- */
- @Override
- protected void startInternal() throws LifecycleException {
-
+ protected UserDatabase getDatabase() {
+
try {
- Context context = getServer().getGlobalNamingContext();
- database = (UserDatabase) context.lookup(resourceName);
+ Context context = null;
+ if (localDataSource) {
+ context = ContextBindings.getClassLoader();
+ context = (Context) context.lookup("comp/env");
+ } else {
+ context = getServer().getGlobalNamingContext();
+ }
+ return (UserDatabase) context.lookup(resourceName);
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
containerLog.error(sm.getString("userDatabaseRealm.lookup",
resourceName),
e);
- database = null;
- }
- if (database == null) {
- throw new LifecycleException
- (sm.getString("userDatabaseRealm.noDatabase", resourceName));
+ return null;
}
-
- super.startInternal();
}
/**
- * Gracefully terminate the active use of the public methods of this
- * component and implement the requirements of
- * {@link org.apache.catalina.util.LifecycleBase#stopInternal()}.
- *
- * @exception LifecycleException if this component detects a fatal error
- * that needs to be reported
+ * Return if the datasource will be looked up in the webapp JNDI Context.
*/
- @Override
- protected void stopInternal() throws LifecycleException {
+ public boolean getLocalDataSource() {
+ return localDataSource;
+ }
- // Perform normal superclass finalization
- super.stopInternal();
- // Release reference to our user database
- database = null;
+ /**
+ * Set to true to cause the datasource to be looked up in the webapp JNDI
+ * Context.
+ *
+ * @param localDataSource the new flag value
+ */
+ public void setLocalDataSource(boolean localDataSource) {
+ this.localDataSource = localDataSource;
+ }
- }
+
}
diff --git a/webapps/docs/config/realm.xml b/webapps/docs/config/realm.xml
index cbf0ddf..98cbbc5 100644
--- a/webapps/docs/config/realm.xml
+++ b/webapps/docs/config/realm.xml
@@ -688,6 +688,13 @@
are defined in web.xml in which case the user must be assigned at least
one of those roles.
+
+ When the realm is nested inside a Context element, this allows the
+ realm to use a DataSource defined for the Context rather than a global
+ DataSource. If not specified, the default is false
: use a
+ global DataSource.
The name of the global UserDatabase
resource