Bug 343277 add support for an optional context white list

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@3022 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Jesse McConnell 2011-04-19 15:27:43 +00:00
parent aa398ad41c
commit fe12431d2e
3 changed files with 102 additions and 1 deletions

View File

@ -1,5 +1,6 @@
jetty-7.4.1-SNAPSHOT
+ 343083 Set nested dispatch type.
+ 343277 add support for a context white list
jetty-7.4.0.v20110414
+ 342504 Scanner Listener

View File

@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingListener;
@ -129,6 +130,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority");
private PermissionCollection _permissions;
private String[] _contextWhiteList = null;
private File _tmpDir;
private String _war;
private String _extraClasspath;
@ -978,6 +981,20 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
_permissions = permissions;
}
/**
* Set the context white list
*
* In certain circumstances you want may want to deny access of one webapp from another
* when you may not fully trust the webapp. Setting this white list will enable a
* check when a servlet called getContext(String), validating that the uriInPath
* for the given webapp has been declaratively allows access to the context.
* @param contextWhiteList
*/
public void setContextWhiteList(String[] contextWhiteList)
{
_contextWhiteList = contextWhiteList;
}
/* ------------------------------------------------------------ */
/**
* Set the server classes patterns.
@ -1181,6 +1198,31 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
return resource.getURL();
}
/* ------------------------------------------------------------ */
@Override
public ServletContext getContext(String uripath)
{
ServletContext servletContext = super.getContext(uripath);
if ( servletContext != null && _contextWhiteList != null )
{
for ( String context : _contextWhiteList )
{
if ( context.equals(uripath) )
{
return servletContext;
}
}
return null;
}
else
{
return servletContext;
}
}
}
/* ------------------------------------------------------------ */

View File

@ -12,11 +12,19 @@
// ========================================================================
package org.eclipse.jetty.webapp;
import java.io.IOException;
import java.util.Arrays;
import javax.servlet.GenericServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import junit.framework.Assert;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
@ -96,4 +104,54 @@ public class WebAppContextTest
// This fails:
assertNotNull(ctx.getRealPath("/doesnotexist/"));
}
/**
* tests that the servlet context white list works
*
* @throws Exception
*/
@Test
public void testContextWhiteList() throws Exception
{
Server server = new Server(0);
HandlerList handlers = new HandlerList();
WebAppContext contextA = new WebAppContext(".", "/A");
contextA.addServlet( ServletA.class, "/s");
handlers.addHandler(contextA);
WebAppContext contextB = new WebAppContext(".", "/B");
contextB.addServlet(ServletB.class, "/s");
contextB.setContextWhiteList(new String [] { "/doesnotexist", "/B/s" } );
handlers.addHandler(contextB);
server.setHandler(handlers);
server.start();
// context A should be able to get both A and B servlet contexts
Assert.assertNotNull(contextA.getServletHandler().getServletContext().getContext("/A/s"));
Assert.assertNotNull(contextA.getServletHandler().getServletContext().getContext("/B/s"));
// context B has a contextWhiteList set and should only be able to get ones that are approved
Assert.assertNull(contextB.getServletHandler().getServletContext().getContext("/A/s"));
Assert.assertNotNull(contextB.getServletHandler().getServletContext().getContext("/B/s"));
}
class ServletA extends GenericServlet
{
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
{
this.getServletContext().getContext("/A/s");
}
}
class ServletB extends GenericServlet
{
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
{
this.getServletContext().getContext("/B/s");
}
}
}