You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@locus.apache.org on 2000/07/11 00:55:22 UTC
cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy package.html SecurityCollection.java SecurityConstraint.java
craigmcc 00/07/10 15:55:22
Modified: proposals/catalina/src/share/org/apache/tomcat/deploy
SecurityCollection.java SecurityConstraint.java
Added: proposals/catalina/src/share/org/apache/tomcat/deploy
package.html
Log:
Tune the behavior of these classes so that checks against a specific
constraint do not require any object creations. Also, add a package
documentation file (for Javadoc) that documents the assumptions of how
these objects will be used -- i.e. read-only access once they are
initialized -- because no synchronization declarations are used.
NOTE: Testing these changes has uncovered a bug in the Catalina
implementation of form-based login that will be fixed separately.
Revision Changes Path
1.3 +101 -89 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityCollection.java
Index: SecurityCollection.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityCollection.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SecurityCollection.java 2000/05/03 22:58:26 1.2
+++ SecurityCollection.java 2000/07/10 22:55:22 1.3
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityCollection.java,v 1.2 2000/05/03 22:58:26 craigmcc Exp $
- * $Revision: 1.2 $
- * $Date: 2000/05/03 22:58:26 $
+ * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityCollection.java,v 1.3 2000/07/10 22:55:22 craigmcc Exp $
+ * $Revision: 1.3 $
+ * $Date: 2000/07/10 22:55:22 $
*
* ====================================================================
*
@@ -65,23 +65,19 @@
package org.apache.tomcat.deploy;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-
/**
* Representation of a web resource collection for a web application's security
* constraint, as represented in a <code><web-resource-collection></code>
* element in the deployment descriptor.
* <p>
- * <b>WARNING</b>: The property setting methods in this class are for use by
- * the application logic that parses a web application deployment descriptor.
- * They should not be called by a Context implementation (or an associated
- * Valve or Interceptor that implements the authentication and authorization
- * constraints expressed here).
+ * <b>WARNING</b>: It is assumed that instances of this class will be created
+ * and modified only within the context of a single thread, before the instance
+ * is made visible to the remainder of the application. After that, only read
+ * access is expected. Therefore, none of the read and write access within
+ * this class is synchronized.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.2 $ $Date: 2000/05/03 22:58:26 $
+ * @version $Revision: 1.3 $ $Date: 2000/07/10 22:55:22 $
*/
public final class SecurityCollection {
@@ -94,8 +90,20 @@
* Construct a new security collection instance with default values.
*/
public SecurityCollection() {
+
+ this(null, null);
+
+ }
+
+
+ /**
+ * Construct a new security collection instance with specified values.
+ *
+ * @param name Name of this security collection
+ */
+ public SecurityCollection(String name) {
- super();
+ this(name, null);
}
@@ -103,14 +111,14 @@
/**
* Construct a new security collection instance with specified values.
*
- * @param constraint Security constraint we are attached to
* @param name Name of this security collection
+ * @param description Description of this security collection
*/
- public SecurityCollection(SecurityConstraint constraint, String name) {
+ public SecurityCollection(String name, String description) {
super();
- setConstraint(constraint);
setName(name);
+ setDescription(description);
}
@@ -119,15 +127,15 @@
/**
- * The security constraint we are attached to.
+ * Description of this web resource collection.
*/
- private SecurityConstraint constraint = null;
+ private String description = null;
/**
* The HTTP methods covered by this web resource collection.
*/
- private String[] methods = new String[0];
+ private String methods[] = new String[0];
/**
@@ -137,51 +145,32 @@
/**
- * The URL patterns protected by this security collection, keyed by
- * pattern.
+ * The URL patterns protected by this security collection.
*/
- private Hashtable patterns = new Hashtable();
+ private String patterns[] = new String[0];
// ------------------------------------------------------------- Properties
/**
- * Return the security constraint we are attached to.
+ * Return the description of this web resource collection.
*/
- public SecurityConstraint getConstraint() {
+ public String getDescription() {
- return (this.constraint);
+ return (this.description);
}
/**
- * Set the security constraint we are attached to.
+ * Set the description of this web resource collection.
*
- * @param constraint The associated constraint
+ * @param description The new description
*/
- public void setConstraint(SecurityConstraint constraint) {
+ public void setDescription(String description) {
- // Remove our patterns from the old constraint (if any)
- if (this.constraint != null) {
- Enumeration currentPatterns = this.patterns.keys();
- while (currentPatterns.hasMoreElements()) {
- String currentPattern = (String) currentPatterns.nextElement();
- this.constraint.removePattern(currentPattern);
- }
- }
-
- this.constraint = constraint;
-
- // Set our patterns in the new constraint (if any)
- if (this.constraint != null) {
- Enumeration currentPatterns = this.patterns.keys();
- while (currentPatterns.hasMoreElements()) {
- String currentPattern = (String) currentPatterns.nextElement();
- this.constraint.addPattern(currentPattern, this);
- }
- }
+ this.description = description;
}
@@ -218,16 +207,11 @@
if (method == null)
return;
- synchronized (methods) {
- String results[] = new String[methods.length + 1];
- for (int i = 0; i < methods.length; i++) {
- if (method.equals(methods[i]))
- return;
- results[i] = methods[i];
- }
- results[results.length - 1] = method;
- methods = results;
- }
+ String results[] = new String[methods.length + 1];
+ for (int i = 0; i < methods.length; i++)
+ results[i] = methods[i];
+ results[methods.length] = method;
+ methods = results;
}
@@ -237,9 +221,13 @@
*/
public void addPattern(String pattern) {
- patterns.put(pattern, pattern);
- if (constraint != null)
- constraint.addPattern(pattern, this);
+ if (pattern == null)
+ return;
+ String results[] = new String[patterns.length + 1];
+ for (int i = 0; i < patterns.length; i++)
+ results[i] = patterns[i];
+ results[patterns.length] = pattern;
+ patterns = results;
}
@@ -252,12 +240,10 @@
*/
public boolean findMethod(String method) {
- if (method == null)
- return (false);
if (methods.length == 0)
return (true);
for (int i = 0; i < methods.length; i++) {
- if (method.equals(methods[i]))
+ if (methods[i].equals(method))
return (true);
}
return (false);
@@ -266,13 +252,29 @@
/**
+ * Return the set of HTTP request methods that are part of this web
+ * resource collection, or a zero-length array if all request methods
+ * are included.
+ */
+ public String[] findMethods() {
+
+ return (methods);
+
+ }
+
+
+ /**
* Is the specified pattern part of this web resource collection?
*
* @param pattern Pattern to be compared
*/
public boolean findPattern(String pattern) {
- return (patterns.get(pattern) != null);
+ for (int i = 0; i < patterns.length; i++) {
+ if (patterns[i].equals(pattern))
+ return (true);
+ }
+ return (false);
}
@@ -284,13 +286,7 @@
*/
public String[] findPatterns() {
- synchronized (patterns) {
- String results[] = new String[patterns.size()];
- Enumeration urls = patterns.keys();
- for (int i = 0; i < results.length; i++)
- results[i] = (String) urls.nextElement();
- return (results);
- }
+ return (patterns);
}
@@ -305,26 +301,23 @@
if (method == null)
return;
- synchronized (methods) {
- int n = -1;
- for (int i = 0; i < methods.length; i++) {
- if (method.equals(methods[i])) {
- n = i;
- break;
- }
+ int n = -1;
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].equals(method)) {
+ n = i;
+ break;
}
- if (n < 0)
- return;
- String results[] = new String[methods.length - 1];
+ }
+ if (n >= 0) {
int j = 0;
+ String results[] = new String[methods.length - 1];
for (int i = 0; i < methods.length; i++) {
- if (i == n)
- continue;
- results[j++] = methods[i];
+ if (i != n)
+ results[j++] = methods[i];
}
methods = results;
}
-
+
}
@@ -336,9 +329,24 @@
*/
public void removePattern(String pattern) {
- patterns.remove(pattern);
- if (constraint != null)
- constraint.removePattern(pattern);
+ if (pattern == null)
+ return;
+ int n = -1;
+ for (int i = 0; i < patterns.length; i++) {
+ if (patterns[i].equals(pattern)) {
+ n = i;
+ break;
+ }
+ }
+ if (n >= 0) {
+ int j = 0;
+ String results[] = new String[patterns.length - 1];
+ for (int i = 0; i < patterns.length; i++) {
+ if (i != n)
+ results[j++] = patterns[i];
+ }
+ patterns = results;
+ }
}
@@ -350,6 +358,10 @@
StringBuffer sb = new StringBuffer("SecurityCollection[");
sb.append(name);
+ if (description != null) {
+ sb.append(", ");
+ sb.append(description);
+ }
sb.append("]");
return (sb.toString());
1.3 +101 -136 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityConstraint.java
Index: SecurityConstraint.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityConstraint.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SecurityConstraint.java 2000/05/03 22:58:27 1.2
+++ SecurityConstraint.java 2000/07/10 22:55:22 1.3
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityConstraint.java,v 1.2 2000/05/03 22:58:27 craigmcc Exp $
- * $Revision: 1.2 $
- * $Date: 2000/05/03 22:58:27 $
+ * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/SecurityConstraint.java,v 1.3 2000/07/10 22:55:22 craigmcc Exp $
+ * $Revision: 1.3 $
+ * $Date: 2000/07/10 22:55:22 $
*
* ====================================================================
*
@@ -65,23 +65,19 @@
package org.apache.tomcat.deploy;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-
/**
* Representation of a security constraint element for a web application,
* as represented in a <code><security-constraint></code> element in the
* deployment descriptor.
* <p>
- * <b>WARNING</b>: The property setting methods in this class are for use by
- * the application logic that parses a web application deployment descriptor.
- * They should not be called by a Context implementation (or an associated
- * Valve or Interceptor that implements the authentication and authorization
- * constraints expressed here).
+ * <b>WARNING</b>: It is assumed that instances of this class will be created
+ * and modified only within the context of a single thread, before the instance
+ * is made visible to the remainder of the application. After that, only read
+ * access is expected. Therefore, none of the read and write access within
+ * this class is synchronized.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.2 $ $Date: 2000/05/03 22:58:27 $
+ * @version $Revision: 1.3 $ $Date: 2000/07/10 22:55:22 $
*/
public final class SecurityConstraint {
@@ -112,20 +108,12 @@
/**
* The set of web resource collections protected by this security
- * constraint, keyed by resource collection name.
+ * constraint.
*/
- private Hashtable collections = new Hashtable();
+ private SecurityCollection collections[] = new SecurityCollection[0];
/**
- * The URL patterns that are parts of the web resource collections
- * managed by this security constraint. The key is the pattern itself,
- * while the value is the corresponding collection.
- */
- private Hashtable patterns = new Hashtable();
-
-
- /**
* The user data constraint for this security constraint. Must be NONE,
* INTEGRAL, or CONFIDENTIAL.
*/
@@ -165,21 +153,17 @@
* Add an authorization role, which is a role name that will be
* permitted access to the resources protected by this security constraint.
*
- * @param role Role name to be added
+ * @param authRole Role name to be added
*/
- public void addAuthRole(String role) {
+ public void addAuthRole(String authRole) {
- if (role == null)
+ if (authRole == null)
return;
- synchronized (authRoles) {
- if (findAuthRole(role))
- return;
- String newRoles[] = new String[authRoles.length + 1];
- for (int i = 0; i < authRoles.length; i++)
- newRoles[i] = authRoles[i];
- newRoles[newRoles.length - 1] = role;
- authRoles = newRoles;
- }
+ String results[] = new String[authRoles.length + 1];
+ for (int i = 0; i < authRoles.length; i++)
+ results[i] = authRoles[i];
+ results[authRoles.length] = authRole;
+ authRoles = results;
}
@@ -191,20 +175,15 @@
* @param collection The new web resource collection
*/
public void addCollection(SecurityCollection collection) {
-
- collections.put(collection.getName(), collection);
- }
-
-
- /**
- * Create and return a web resource collection with default values.
- *
- * @param name Name of the new web resource collection
- */
- public SecurityCollection createCollection(String name) {
-
- return (new SecurityCollection(this, name));
+ if (collection == null)
+ return;
+ SecurityCollection results[] =
+ new SecurityCollection[collections.length + 1];
+ for (int i = 0; i < collections.length; i++)
+ results[i] = collections[i];
+ results[collections.length] = collection;
+ collections = results;
}
@@ -219,11 +198,9 @@
if (role == null)
return (false);
- synchronized (authRoles) {
- for (int i = 0; i < authRoles.length; i++) {
- if (role.equals(authRoles[i]))
- return (true);
- }
+ for (int i = 0; i < authRoles.length; i++) {
+ if (role.equals(authRoles[i]))
+ return (true);
}
return (false);
@@ -238,7 +215,7 @@
*/
public String[] findAuthRoles() {
- return (authRoles); // Assumption - caller will not modify
+ return (authRoles);
}
@@ -251,25 +228,25 @@
*/
public SecurityCollection findCollection(String name) {
- return ((SecurityCollection) collections.get(name));
+ if (name == null)
+ return (null);
+ for (int i = 0; i < collections.length; i++) {
+ if (name.equals(collections[i].getName()))
+ return (collections[i]);
+ }
+ return (null);
}
/**
- * Return the names of all web resource collections protected by this
+ * Return all of the web resource collections protected by this
* security constraint. If there are none, a zero-length array is
* returned.
*/
- public String[] findCollections() {
+ public SecurityCollection[] findCollections() {
- synchronized (collections) {
- String results[] = new String[collections.size()];
- Enumeration names = collections.keys();
- for (int i = 0; i < results.length; i++)
- results[i] = (String) names.nextElement();
- return (results);
- }
+ return (collections);
}
@@ -283,22 +260,23 @@
*/
public boolean included(String uri, String method) {
- // Check all defined patterns
- SecurityCollection collection = null;
- Enumeration patterns = this.patterns.keys();
- while (patterns.hasMoreElements()) {
- String pattern = (String) patterns.nextElement();
- if (matchPattern(uri, pattern)) {
- collection = (SecurityCollection) this.patterns.get(pattern);
- break;
+ // We cannot match without a valid request method
+ if (method == null)
+ return (false);
+
+ // Check all of the collections included in this constraint
+ for (int i = 0; i < collections.length; i++) {
+ if (!collections[i].findMethod(method))
+ continue;
+ String patterns[] = collections[i].findPatterns();
+ for (int j = 0; j < patterns.length; j++) {
+ if (matchPattern(uri, patterns[j]))
+ return (true);
}
}
- // Match on HTTP request method as well
- if (collection == null)
- return (false);
- else
- return (collection.findMethod(method));
+ // No collection included in this constraint matches this request
+ return (false);
}
@@ -307,23 +285,27 @@
* Remove the specified role from the set of roles permitted to access
* the resources protected by this security constraint.
*
- * @param role Role name to be removed
+ * @param authRole Role name to be removed
*/
- public void removeAuthRole(String role) {
+ public void removeAuthRole(String authRole) {
- if (role == null)
+ if (authRole == null)
return;
- synchronized (authRoles) {
- if (!findAuthRole(role))
- return;
- String newRoles[] = new String[authRoles.length - 1];
+ int n = -1;
+ for (int i = 0; i < authRoles.length; i++) {
+ if (authRoles[i].equals(authRole)) {
+ n = i;
+ break;
+ }
+ }
+ if (n >= 0) {
int j = 0;
+ String results[] = new String[authRoles.length - 1];
for (int i = 0; i < authRoles.length; i++) {
- if (role.equals(authRoles[i]))
- continue;
- newRoles[j++] = authRoles[i];
+ if (i != n)
+ results[j++] = authRoles[i];
}
- authRoles = newRoles;
+ authRoles = results;
}
}
@@ -337,7 +319,25 @@
*/
public void removeCollection(SecurityCollection collection) {
- collections.remove(collection.getName());
+ if (collection == null)
+ return;
+ int n = -1;
+ for (int i = 0; i < collections.length; i++) {
+ if (collections[i].equals(collection)) {
+ n = i;
+ break;
+ }
+ }
+ if (n >= 0) {
+ int j = 0;
+ SecurityCollection results[] =
+ new SecurityCollection[collections.length - 1];
+ for (int i = 0; i < collections.length; i++) {
+ if (i != n)
+ results[j++] = collections[i];
+ }
+ collections = results;
+ }
}
@@ -348,16 +348,10 @@
public String toString() {
StringBuffer sb = new StringBuffer("SecurityConstraint[");
- int n = 0;
- Enumeration names = collections.keys();
- while (names.hasMoreElements()) {
- String name = (String) names.nextElement();
- if (n > 0)
- sb.append(",");
- sb.append("(");
- sb.append(name);
- sb.append(")");
- n++;
+ for (int i = 0; i < collections.length; i++) {
+ if (i > 0)
+ sb.append(", ");
+ sb.append(collections[i].getName());
}
sb.append("]");
return (sb.toString());
@@ -365,44 +359,14 @@
}
- // ------------------------------------------------ Package Private Methods
-
-
- /**
- * Add a URL pattern that is part of one of our constituent web resource
- * collections.
- *
- * @param pattern URL pattern to be added
- * @param collection The corresponding collection
- */
- void addPattern(String pattern, SecurityCollection collection) {
-
- patterns.put(pattern, collection);
-
- }
-
-
- /**
- * Remove a URL pattern that was part of one of our constituent web
- * resource collections.
- *
- * @param pattern URL pattern to be removed
- */
- void removePattern(String pattern) {
-
- patterns.remove(pattern);
-
- }
-
-
// -------------------------------------------------------- Private Methods
/**
* Does the specified request path match the specified URL pattern?
+ * This method follows the same rules (in the same order) as those used
+ * for mapping requests to servlets.
*
- * XXX - Shouldn't this be a shared utility method someplace?
- *
* @param path Context-relative request path to be checked
* (must start with '/')
* @param pattern URL pattern to be compared against
@@ -419,10 +383,6 @@
if (path.equals(pattern))
return (true);
- // Check for universal mapping
- if (pattern.equals("/"))
- return (true);
-
// Check for path prefix matching
if (pattern.startsWith("/") && pattern.endsWith("/*")) {
pattern = pattern.substring(0, pattern.length() - 2);
@@ -442,14 +402,19 @@
}
// Check for suffix matching
- else if (pattern.startsWith("*.")) {
+ if (pattern.startsWith("*.")) {
int slash = path.lastIndexOf('/');
int period = path.lastIndexOf('.');
if ((slash >= 0) && (period > slash) &&
path.endsWith(pattern.substring(1))) {
return (true);
}
+ return (false);
}
+
+ // Check for universal mapping
+ if (pattern.equals("/"))
+ return (true);
return (false);
1.1 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/deploy/package.html
Index: package.html
===================================================================
This package contains Java objects that represent complex data structures
from the web application deployment descriptor file (<code>web.xml</code>).
It is assumed that these objects will be initialized within the context of
a single thread, and then referenced in a read-only manner subsequent to that
time. Therefore, no multi-thread synchronization is utilized within the
implementation classes.