import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
+import javax.servlet.ServletSecurityElement;
import javax.servlet.descriptor.JspConfigDescriptor;
+import org.apache.catalina.core.ApplicationServletRegistration;
import org.apache.catalina.deploy.ApplicationParameter;
import org.apache.catalina.deploy.ErrorPage;
import org.apache.catalina.deploy.FilterDef;
* Is this context using version 2.2 of the Servlet spec?
*/
boolean isServlet22();
+
+ /**
+ * Notification that servlet security has been dynamically set in a
+ * {@Link ServletRegistration.Dynamic}
+ * @param registration servlet security was modified for
+ * @param servletSecurityElement new security constraints for this servlet
+ * @return urls currently mapped to this registration that are already
+ * present in web.xml
+ */
+ Set<String> addServletSecurity(ApplicationServletRegistration registration,
+ ServletSecurityElement servletSecurityElement);
}
// Have to add in a separate loop since spec requires no updates at all
// if there is an issue
- for (Map.Entry<String, String> entry : initParameters.entrySet()) {
- setInitParameter(entry.getKey(), entry.getValue());
+ if (conflicts.isEmpty()) {
+ for (Map.Entry<String, String> entry : initParameters.entrySet()) {
+ setInitParameter(entry.getKey(), entry.getValue());
+ }
}
-
+
return conflicts;
}
getName(), context.getPath()));
}
- Set<String> conflicts = new HashSet<String>();
-
- Collection<String> urlPatterns = getMappings();
- for (String urlPattern : urlPatterns) {
- boolean foundConflict = false;
-
- SecurityConstraint[] securityConstraints =
- context.findConstraints();
- for (SecurityConstraint securityConstraint : securityConstraints) {
-
- SecurityCollection[] collections =
- securityConstraint.findCollections();
- for (SecurityCollection collection : collections) {
- if (collection.findPattern(urlPattern)) {
- // First pattern found will indicate if there is a
- // conflict since for any given pattern all matching
- // constraints will be from either the descriptor or
- // not. It is not permitted to have a mixture
- if (collection.isFromDescriptor()) {
- // Skip this pattern
- foundConflict = true;
- } else {
- // Need to overwrite constraint for this pattern
- // so remove every pattern found
- context.removeConstraint(securityConstraint);
- }
- }
- if (foundConflict) {
- break;
- }
- }
- if (foundConflict) {
- break;
- }
- }
- if (!foundConflict) {
- SecurityConstraint[] newSecurityConstraints =
- SecurityConstraint.createConstraints(constraint,
- urlPattern);
- for (SecurityConstraint securityConstraint :
- newSecurityConstraints) {
- context.addConstraint(securityConstraint);
- }
- }
- }
-
- return conflicts;
+ return context.addServletSecurity(this, constraint);
}
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.servlet.FilterConfig;
+import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
+import javax.servlet.ServletSecurityElement;
import javax.servlet.descriptor.JspConfigDescriptor;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionListener;
return null;
}
+ /**
+ * hook to register that we need to scan for security annotations.
+ * @param registration
+ */
+ public ServletRegistration.Dynamic dynamicServletAdded(Wrapper wrapper) {
+ return new ApplicationServletRegistration(wrapper, this);
+ }
+
+ /**
+ * hook to track which registrations need annotation scanning
+ * @param servlet
+ */
+ public void dynamicServletCreated(Servlet servlet) {
+ // NOOP - Hook for JACC implementations
+ }
+
/**
* A helper class to manage the filter mappings in a Context.
}
+ public Set<String> addServletSecurity(
+ ApplicationServletRegistration registration,
+ ServletSecurityElement servletSecurityElement) {
+
+ Set<String> conflicts = new HashSet<String>();
+
+ Collection<String> urlPatterns = registration.getMappings();
+ for (String urlPattern : urlPatterns) {
+ boolean foundConflict = false;
+
+ SecurityConstraint[] securityConstraints =
+ findConstraints();
+ for (SecurityConstraint securityConstraint : securityConstraints) {
+
+ SecurityCollection[] collections =
+ securityConstraint.findCollections();
+ for (SecurityCollection collection : collections) {
+ if (collection.findPattern(urlPattern)) {
+ // First pattern found will indicate if there is a
+ // conflict since for any given pattern all matching
+ // constraints will be from either the descriptor or
+ // not. It is not permitted to have a mixture
+ if (collection.isFromDescriptor()) {
+ // Skip this pattern
+ foundConflict = true;
+ conflicts.add(urlPattern);
+ } else {
+ // Need to overwrite constraint for this pattern
+ // so remove every pattern found
+
+ // TODO spec 13.4.2 appears to say only the
+ // conflicting pattern is overwritten, not the
+ // entire security constraint.
+ removeConstraint(securityConstraint);
+ }
+ }
+ if (foundConflict) {
+ break;
+ }
+ }
+ if (foundConflict) {
+ break;
+ }
+ }
+ // TODO spec 13.4.2 appears to say that non-conflicting patterns are
+ // still used.
+ // TODO you can't calculate the eventual security constraint now,
+ // you have to wait until the context is started, since application
+ // code can add url patterns after calling setSecurity.
+ if (!foundConflict) {
+ SecurityConstraint[] newSecurityConstraints =
+ SecurityConstraint.createConstraints(
+ servletSecurityElement,
+ urlPattern);
+ for (SecurityConstraint securityConstraint :
+ newSecurityConstraints) {
+ addConstraint(securityConstraint);
+ }
+ }
+ }
+
+ return conflicts;
+
+ }
+
/**
* Return a File object representing the base directory for the