Author: rjung Date: Sun Nov 30 18:30:47 2014 New Revision: 1642595 URL: http://svn.apache.org/r1642595 Log: Allow RemoteAddreValve and RemoteHostValve to trigger authentication instead of denying a request with a status code.
This only works in combination with preemptiveAuthentication on the application context. It can be used to add an additional authentication without touching the application war. Example: <Context preemptiveAuthentication="true"> <Valve className="org.apache.catalina.valves.RequestFilterValve" allow=".*,8009" addLocalPort="true" invalidAuthenticationWhenDeny="true"/> <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" /> </Context> This will allow normal access via the port 8009 connector (AJP) but will trigger basic auth when accessed via any other connector. An administrator can use an http port to check whether the app works but public access will still be restricted to the AJP port. Modified: tomcat/trunk/java/org/apache/catalina/valves/RequestFilterValve.java tomcat/trunk/test/org/apache/catalina/valves/TestRequestFilterValve.java tomcat/trunk/webapps/docs/config/valve.xml Modified: tomcat/trunk/java/org/apache/catalina/valves/RequestFilterValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/RequestFilterValve.java?rev=1642595&r1=1642594&r2=1642595&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/valves/RequestFilterValve.java (original) +++ tomcat/trunk/java/org/apache/catalina/valves/RequestFilterValve.java Sun Nov 30 18:30:47 2014 @@ -23,6 +23,7 @@ import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; +import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; @@ -52,6 +53,11 @@ import org.apache.catalina.connector.Res * <li>The request will be rejected with a "Forbidden" HTTP response.</li> * </ul> * <p> + * As an option the valve can generate an invalid <code>authenticate</code> + * header instead of denying the request. This can be combined with the + * context attribute <code>preemptiveAuthentication="true"</code> and an + * authenticator to force authentication instead of denial. + * <p> * This Valve may be attached to any Container, depending on the granularity * of the filtering you wish to perform. * @@ -117,6 +123,14 @@ public abstract class RequestFilterValve */ protected int denyStatus = HttpServletResponse.SC_FORBIDDEN; + /** + * <p>If <code>invalidAuthenticationWhenDeny</code> is true + * and the context has <code>preemptiveAuthentication</code> + * set, set an invalid authorization header to trigger basic auth + * instead of denying the request.. + */ + private boolean invalidAuthenticationWhenDeny = false; + // ------------------------------------------------------------- Properties @@ -221,6 +235,23 @@ public abstract class RequestFilterValve this.denyStatus = denyStatus; } + + /** + * Return true if a deny is handled by setting an invalid auth header. + */ + public boolean getInvalidAuthenticationWhenDeny() { + return invalidAuthenticationWhenDeny; + } + + + /** + * Set invalidAuthenticationWhenDeny property. + */ + public void setInvalidAuthenticationWhenDeny(boolean value) { + invalidAuthenticationWhenDeny = value; + } + + // --------------------------------------------------------- Public Methods /** @@ -290,6 +321,9 @@ public abstract class RequestFilterValve /** * Reject the request that was denied by this valve. + * <p>If <code>invalidAuthenticationWhenDeny</code> is true + * and the context has <code>preemptiveAuthentication</code> + * set, set an invalid authorization header to trigger basic auth. * * @param request The servlet request to be processed * @param response The servlet response to be processed @@ -298,6 +332,16 @@ public abstract class RequestFilterValve */ protected void denyRequest(Request request, Response response) throws IOException, ServletException { + if (invalidAuthenticationWhenDeny) { + Context context = request.getContext(); + if (context != null && context.getPreemptiveAuthentication()) { + if (request.getCoyoteRequest().getMimeHeaders().getValue("authorization") == null) { + request.getCoyoteRequest().getMimeHeaders().addValue("authorization").setString("invalid"); + } + getNext().invoke(request, response); + return; + } + } response.sendError(denyStatus); } Modified: tomcat/trunk/test/org/apache/catalina/valves/TestRequestFilterValve.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/valves/TestRequestFilterValve.java?rev=1642595&r1=1642594&r2=1642595&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/valves/TestRequestFilterValve.java (original) +++ tomcat/trunk/test/org/apache/catalina/valves/TestRequestFilterValve.java Sun Nov 30 18:30:47 2014 @@ -26,9 +26,11 @@ import static org.junit.Assert.fail; import org.junit.Test; +import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; +import org.apache.catalina.core.StandardContext; /** * {@link RequestFilterValve} Tests @@ -79,11 +81,12 @@ public class TestRequestFilterValve { } private void oneTest(String allow, String deny, boolean denyStatus, - boolean addLocalPort, + boolean addLocalPort, boolean auth, String property, String type, boolean allowed) { // PREPARE RequestFilterValve valve = null; Connector connector = new Connector(); + Context context = new StandardContext(); Request request = new Request(); Response response = new MockResponse(); StringBuilder msg = new StringBuilder(); @@ -91,6 +94,8 @@ public class TestRequestFilterValve { connector.setPort(PORT); request.setConnector(connector); + request.setContext(context); + request.setCoyoteRequest(new org.apache.coyote.Request()); if (type == null) { fail("Invalid test with null type"); @@ -135,6 +140,11 @@ public class TestRequestFilterValve { } msg.append(" addLocalPort='true'"); } + if (auth) { + context.setPreemptiveAuthentication(true); + valve.setInvalidAuthenticationWhenDeny(true); + msg.append(" auth='true'"); + } // TEST try { @@ -146,169 +156,174 @@ public class TestRequestFilterValve { } // VERIFY - assertEquals(msg.toString(), expected, response.getStatus()); + if (!allowed && auth) { + assertEquals(msg.toString(), OK, response.getStatus()); + assertEquals(msg.toString(), "invalid", request.getHeader("authorization")); + } else { + assertEquals(msg.toString(), expected, response.getStatus()); + } } private void standardTests(String allow_pat, String deny_pat, String OnlyAllow, String OnlyDeny, String AllowAndDeny, String NoAllowNoDeny, - String type) { + boolean auth, String type) { String apat; String dpat; // Test without ports apat = allow_pat; dpat = deny_pat; - oneTest(null, null, false, false, AllowAndDeny, type, false); - oneTest(null, null, true, false, AllowAndDeny, type, false); - oneTest(apat, null, false, false, AllowAndDeny, type, true); - oneTest(apat, null, false, false, NoAllowNoDeny, type, false); - oneTest(apat, null, true, false, AllowAndDeny, type, true); - oneTest(apat, null, true, false, NoAllowNoDeny, type, false); - oneTest(null, dpat, false, false, AllowAndDeny, type, false); - oneTest(null, dpat, false, false, NoAllowNoDeny, type, true); - oneTest(null, dpat, true, false, AllowAndDeny, type, false); - oneTest(null, dpat, true, false, NoAllowNoDeny, type, true); - oneTest(apat, dpat, false, false, NoAllowNoDeny, type, false); - oneTest(apat, dpat, false, false, OnlyAllow, type, true); - oneTest(apat, dpat, false, false, OnlyDeny, type, false); - oneTest(apat, dpat, false, false, AllowAndDeny, type, false); - oneTest(apat, dpat, true, false, NoAllowNoDeny, type, false); - oneTest(apat, dpat, true, false, OnlyAllow, type, true); - oneTest(apat, dpat, true, false, OnlyDeny, type, false); - oneTest(apat, dpat, true, false, AllowAndDeny, type, false); + oneTest(null, null, false, false, auth, AllowAndDeny, type, false); + oneTest(null, null, true, false, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, false, auth, AllowAndDeny, type, true); + oneTest(apat, null, false, false, auth, NoAllowNoDeny, type, false); + oneTest(apat, null, true, false, auth, AllowAndDeny, type, true); + oneTest(apat, null, true, false, auth, NoAllowNoDeny, type, false); + oneTest(null, dpat, false, false, auth, AllowAndDeny, type, false); + oneTest(null, dpat, false, false, auth, NoAllowNoDeny, type, true); + oneTest(null, dpat, true, false, auth, AllowAndDeny, type, false); + oneTest(null, dpat, true, false, auth, NoAllowNoDeny, type, true); + oneTest(apat, dpat, false, false, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, false, false, auth, OnlyAllow, type, true); + oneTest(apat, dpat, false, false, auth, OnlyDeny, type, false); + oneTest(apat, dpat, false, false, auth, AllowAndDeny, type, false); + oneTest(apat, dpat, true, false, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, true, false, auth, OnlyAllow, type, true); + oneTest(apat, dpat, true, false, auth, OnlyDeny, type, false); + oneTest(apat, dpat, true, false, auth, AllowAndDeny, type, false); // Test with port in pattern but forgotten "addLocalPort" apat = allow_pat + PORT_MATCH_PATTERN; dpat = deny_pat + PORT_MATCH_PATTERN; - oneTest(null, null, false, false, AllowAndDeny, type, false); - oneTest(null, null, true, false, AllowAndDeny, type, false); - oneTest(apat, null, false, false, AllowAndDeny, type, false); - oneTest(apat, null, false, false, NoAllowNoDeny, type, false); - oneTest(apat, null, true, false, AllowAndDeny, type, false); - oneTest(apat, null, true, false, NoAllowNoDeny, type, false); - oneTest(null, dpat, false, false, AllowAndDeny, type, true); - oneTest(null, dpat, false, false, NoAllowNoDeny, type, true); - oneTest(null, dpat, true, false, AllowAndDeny, type, true); - oneTest(null, dpat, true, false, NoAllowNoDeny, type, true); - oneTest(apat, dpat, false, false, NoAllowNoDeny, type, false); - oneTest(apat, dpat, false, false, OnlyAllow, type, false); - oneTest(apat, dpat, false, false, OnlyDeny, type, false); - oneTest(apat, dpat, false, false, AllowAndDeny, type, false); - oneTest(apat, dpat, true, false, NoAllowNoDeny, type, false); - oneTest(apat, dpat, true, false, OnlyAllow, type, false); - oneTest(apat, dpat, true, false, OnlyDeny, type, false); - oneTest(apat, dpat, true, false, AllowAndDeny, type, false); + oneTest(null, null, false, false, auth, AllowAndDeny, type, false); + oneTest(null, null, true, false, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, false, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, false, auth, NoAllowNoDeny, type, false); + oneTest(apat, null, true, false, auth, AllowAndDeny, type, false); + oneTest(apat, null, true, false, auth, NoAllowNoDeny, type, false); + oneTest(null, dpat, false, false, auth, AllowAndDeny, type, true); + oneTest(null, dpat, false, false, auth, NoAllowNoDeny, type, true); + oneTest(null, dpat, true, false, auth, AllowAndDeny, type, true); + oneTest(null, dpat, true, false, auth, NoAllowNoDeny, type, true); + oneTest(apat, dpat, false, false, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, false, false, auth, OnlyAllow, type, false); + oneTest(apat, dpat, false, false, auth, OnlyDeny, type, false); + oneTest(apat, dpat, false, false, auth, AllowAndDeny, type, false); + oneTest(apat, dpat, true, false, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, true, false, auth, OnlyAllow, type, false); + oneTest(apat, dpat, true, false, auth, OnlyDeny, type, false); + oneTest(apat, dpat, true, false, auth, AllowAndDeny, type, false); // Test with "addLocalPort" but port not in pattern apat = allow_pat; dpat = deny_pat; - oneTest(null, null, false, true, AllowAndDeny, type, false); - oneTest(null, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, NoAllowNoDeny, type, false); - oneTest(apat, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, true, true, NoAllowNoDeny, type, false); - oneTest(null, dpat, false, true, AllowAndDeny, type, true); - oneTest(null, dpat, false, true, NoAllowNoDeny, type, true); - oneTest(null, dpat, true, true, AllowAndDeny, type, true); - oneTest(null, dpat, true, true, NoAllowNoDeny, type, true); - oneTest(apat, dpat, false, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, false, true, OnlyAllow, type, false); - oneTest(apat, dpat, false, true, OnlyDeny, type, false); - oneTest(apat, dpat, false, true, AllowAndDeny, type, false); - oneTest(apat, dpat, true, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, true, true, OnlyAllow, type, false); - oneTest(apat, dpat, true, true, OnlyDeny, type, false); - oneTest(apat, dpat, true, true, AllowAndDeny, type, false); + oneTest(null, null, false, true, auth, AllowAndDeny, type, false); + oneTest(null, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, true, true, auth, NoAllowNoDeny, type, false); + oneTest(null, dpat, false, true, auth, AllowAndDeny, type, true); + oneTest(null, dpat, false, true, auth, NoAllowNoDeny, type, true); + oneTest(null, dpat, true, true, auth, AllowAndDeny, type, true); + oneTest(null, dpat, true, true, auth, NoAllowNoDeny, type, true); + oneTest(apat, dpat, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, false, true, auth, OnlyAllow, type, false); + oneTest(apat, dpat, false, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, false, true, auth, AllowAndDeny, type, false); + oneTest(apat, dpat, true, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, true, true, auth, OnlyAllow, type, false); + oneTest(apat, dpat, true, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, true, true, auth, AllowAndDeny, type, false); // Test "addLocalPort" and with port matching in both patterns apat = allow_pat + PORT_MATCH_PATTERN; dpat = deny_pat + PORT_MATCH_PATTERN; - oneTest(null, null, false, true, AllowAndDeny, type, false); - oneTest(null, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, AllowAndDeny, type, true); - oneTest(apat, null, false, true, NoAllowNoDeny, type, false); - oneTest(apat, null, true, true, AllowAndDeny, type, true); - oneTest(apat, null, true, true, NoAllowNoDeny, type, false); - oneTest(null, dpat, false, true, AllowAndDeny, type, false); - oneTest(null, dpat, false, true, NoAllowNoDeny, type, true); - oneTest(null, dpat, true, true, AllowAndDeny, type, false); - oneTest(null, dpat, true, true, NoAllowNoDeny, type, true); - oneTest(apat, dpat, false, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, false, true, OnlyAllow, type, true); - oneTest(apat, dpat, false, true, OnlyDeny, type, false); - oneTest(apat, dpat, false, true, AllowAndDeny, type, false); - oneTest(apat, dpat, true, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, true, true, OnlyAllow, type, true); - oneTest(apat, dpat, true, true, OnlyDeny, type, false); - oneTest(apat, dpat, true, true, AllowAndDeny, type, false); + oneTest(null, null, false, true, auth, AllowAndDeny, type, false); + oneTest(null, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, AllowAndDeny, type, true); + oneTest(apat, null, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, null, true, true, auth, AllowAndDeny, type, true); + oneTest(apat, null, true, true, auth, NoAllowNoDeny, type, false); + oneTest(null, dpat, false, true, auth, AllowAndDeny, type, false); + oneTest(null, dpat, false, true, auth, NoAllowNoDeny, type, true); + oneTest(null, dpat, true, true, auth, AllowAndDeny, type, false); + oneTest(null, dpat, true, true, auth, NoAllowNoDeny, type, true); + oneTest(apat, dpat, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, false, true, auth, OnlyAllow, type, true); + oneTest(apat, dpat, false, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, false, true, auth, AllowAndDeny, type, false); + oneTest(apat, dpat, true, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, true, true, auth, OnlyAllow, type, true); + oneTest(apat, dpat, true, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, true, true, auth, AllowAndDeny, type, false); // Test "addLocalPort" and with port not matching in both patterns apat = allow_pat + PORT_NO_MATCH_PATTERN; dpat = deny_pat + PORT_NO_MATCH_PATTERN; - oneTest(null, null, false, true, AllowAndDeny, type, false); - oneTest(null, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, NoAllowNoDeny, type, false); - oneTest(apat, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, true, true, NoAllowNoDeny, type, false); - oneTest(null, dpat, false, true, AllowAndDeny, type, true); - oneTest(null, dpat, false, true, NoAllowNoDeny, type, true); - oneTest(null, dpat, true, true, AllowAndDeny, type, true); - oneTest(null, dpat, true, true, NoAllowNoDeny, type, true); - oneTest(apat, dpat, false, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, false, true, OnlyAllow, type, false); - oneTest(apat, dpat, false, true, OnlyDeny, type, false); - oneTest(apat, dpat, false, true, AllowAndDeny, type, false); - oneTest(apat, dpat, true, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, true, true, OnlyAllow, type, false); - oneTest(apat, dpat, true, true, OnlyDeny, type, false); - oneTest(apat, dpat, true, true, AllowAndDeny, type, false); + oneTest(null, null, false, true, auth, AllowAndDeny, type, false); + oneTest(null, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, true, true, auth, NoAllowNoDeny, type, false); + oneTest(null, dpat, false, true, auth, AllowAndDeny, type, true); + oneTest(null, dpat, false, true, auth, NoAllowNoDeny, type, true); + oneTest(null, dpat, true, true, auth, AllowAndDeny, type, true); + oneTest(null, dpat, true, true, auth, NoAllowNoDeny, type, true); + oneTest(apat, dpat, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, false, true, auth, OnlyAllow, type, false); + oneTest(apat, dpat, false, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, false, true, auth, AllowAndDeny, type, false); + oneTest(apat, dpat, true, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, true, true, auth, OnlyAllow, type, false); + oneTest(apat, dpat, true, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, true, true, auth, AllowAndDeny, type, false); // Test "addLocalPort" and with port matching only in allow apat = allow_pat + PORT_MATCH_PATTERN; dpat = deny_pat + PORT_NO_MATCH_PATTERN; - oneTest(null, null, false, true, AllowAndDeny, type, false); - oneTest(null, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, AllowAndDeny, type, true); - oneTest(apat, null, false, true, NoAllowNoDeny, type, false); - oneTest(apat, null, true, true, AllowAndDeny, type, true); - oneTest(apat, null, true, true, NoAllowNoDeny, type, false); - oneTest(null, dpat, false, true, AllowAndDeny, type, true); - oneTest(null, dpat, false, true, NoAllowNoDeny, type, true); - oneTest(null, dpat, true, true, AllowAndDeny, type, true); - oneTest(null, dpat, true, true, NoAllowNoDeny, type, true); - oneTest(apat, dpat, false, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, false, true, OnlyAllow, type, true); - oneTest(apat, dpat, false, true, OnlyDeny, type, false); - oneTest(apat, dpat, false, true, AllowAndDeny, type, true); - oneTest(apat, dpat, true, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, true, true, OnlyAllow, type, true); - oneTest(apat, dpat, true, true, OnlyDeny, type, false); - oneTest(apat, dpat, true, true, AllowAndDeny, type, true); + oneTest(null, null, false, true, auth, AllowAndDeny, type, false); + oneTest(null, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, AllowAndDeny, type, true); + oneTest(apat, null, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, null, true, true, auth, AllowAndDeny, type, true); + oneTest(apat, null, true, true, auth, NoAllowNoDeny, type, false); + oneTest(null, dpat, false, true, auth, AllowAndDeny, type, true); + oneTest(null, dpat, false, true, auth, NoAllowNoDeny, type, true); + oneTest(null, dpat, true, true, auth, AllowAndDeny, type, true); + oneTest(null, dpat, true, true, auth, NoAllowNoDeny, type, true); + oneTest(apat, dpat, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, false, true, auth, OnlyAllow, type, true); + oneTest(apat, dpat, false, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, false, true, auth, AllowAndDeny, type, true); + oneTest(apat, dpat, true, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, true, true, auth, OnlyAllow, type, true); + oneTest(apat, dpat, true, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, true, true, auth, AllowAndDeny, type, true); // Test "addLocalPort" and with port matching only in deny apat = allow_pat + PORT_NO_MATCH_PATTERN; dpat = deny_pat + PORT_MATCH_PATTERN; - oneTest(null, null, false, true, AllowAndDeny, type, false); - oneTest(null, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, AllowAndDeny, type, false); - oneTest(apat, null, false, true, NoAllowNoDeny, type, false); - oneTest(apat, null, true, true, AllowAndDeny, type, false); - oneTest(apat, null, true, true, NoAllowNoDeny, type, false); - oneTest(null, dpat, false, true, AllowAndDeny, type, false); - oneTest(null, dpat, false, true, NoAllowNoDeny, type, true); - oneTest(null, dpat, true, true, AllowAndDeny, type, false); - oneTest(null, dpat, true, true, NoAllowNoDeny, type, true); - oneTest(apat, dpat, false, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, false, true, OnlyAllow, type, false); - oneTest(apat, dpat, false, true, OnlyDeny, type, false); - oneTest(apat, dpat, false, true, AllowAndDeny, type, false); - oneTest(apat, dpat, true, true, NoAllowNoDeny, type, false); - oneTest(apat, dpat, true, true, OnlyAllow, type, false); - oneTest(apat, dpat, true, true, OnlyDeny, type, false); - oneTest(apat, dpat, true, true, AllowAndDeny, type, false); + oneTest(null, null, false, true, auth, AllowAndDeny, type, false); + oneTest(null, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, null, true, true, auth, AllowAndDeny, type, false); + oneTest(apat, null, true, true, auth, NoAllowNoDeny, type, false); + oneTest(null, dpat, false, true, auth, AllowAndDeny, type, false); + oneTest(null, dpat, false, true, auth, NoAllowNoDeny, type, true); + oneTest(null, dpat, true, true, auth, AllowAndDeny, type, false); + oneTest(null, dpat, true, true, auth, NoAllowNoDeny, type, true); + oneTest(apat, dpat, false, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, false, true, auth, OnlyAllow, type, false); + oneTest(apat, dpat, false, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, false, true, auth, AllowAndDeny, type, false); + oneTest(apat, dpat, true, true, auth, NoAllowNoDeny, type, false); + oneTest(apat, dpat, true, true, auth, OnlyAllow, type, false); + oneTest(apat, dpat, true, true, auth, OnlyDeny, type, false); + oneTest(apat, dpat, true, true, auth, AllowAndDeny, type, false); } @Test @@ -316,7 +331,11 @@ public class TestRequestFilterValve { standardTests(ADDR_ALLOW_PAT, ADDR_DENY_PAT, ADDR_ONLY_ALLOW, ADDR_ONLY_DENY, ADDR_ALLOW_AND_DENY, ADDR_NO_ALLOW_NO_DENY, - "Addr"); + false, "Addr"); + standardTests(ADDR_ALLOW_PAT, ADDR_DENY_PAT, + ADDR_ONLY_ALLOW, ADDR_ONLY_DENY, + ADDR_ALLOW_AND_DENY, ADDR_NO_ALLOW_NO_DENY, + true, "Addr"); } @Test @@ -324,6 +343,10 @@ public class TestRequestFilterValve { standardTests(HOST_ALLOW_PAT, HOST_DENY_PAT, HOST_ONLY_ALLOW, HOST_ONLY_DENY, HOST_ALLOW_AND_DENY, HOST_NO_ALLOW_NO_DENY, - "Host"); + false, "Host"); + standardTests(HOST_ALLOW_PAT, HOST_DENY_PAT, + HOST_ONLY_ALLOW, HOST_ONLY_DENY, + HOST_ALLOW_AND_DENY, HOST_NO_ALLOW_NO_DENY, + true, "Host"); } } Modified: tomcat/trunk/webapps/docs/config/valve.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/valve.xml?rev=1642595&r1=1642594&r2=1642595&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/valve.xml (original) +++ tomcat/trunk/webapps/docs/config/valve.xml Sun Nov 30 18:30:47 2014 @@ -476,6 +476,11 @@ <p>Optionally one can append the local server port separated with a comma (",") to allow different expressions for each connector.</p> + <p>The behavior when a request is refused can be changed + to not deny but instead set an invalid <code>authentication</code> + header. This is useful in combination with the context attribute + <code>preemptiveAuthentication="true"</code>.</p> + <p><strong>Note:</strong> There is a caveat when using this valve with IPv6 addresses. Format of the IP address that this valve is processing depends on the API that was used to obtain it. If the address was obtained @@ -533,6 +538,17 @@ request. The default value is <code>false</code>.</p> </attribute> + <attribute name="invalidAuthenticationWhenDeny" required="false"> + <p>When a request should be denied, do not deny but instead + set an invalid <code>authentication</code> header. This only works + if the context has the attribute <code>preemptiveAuthentication="true"</code> + set. An already existing <code>authentication</code> header will not be + overwritten. In effect this will trigger authentication instead of deny + even if the application does not have a security constraint configured.</p> + <p>This can be combined with <code>addLocalPort</code> to trigger authentication + depending on the client and the port that is used to access an application.</p> + </attribute> + </attributes> </subsection> @@ -575,6 +591,11 @@ <p>Optionally one can append the local server port separated with a comma (",") to allow different expressions for each connector.</p> + <p>The behavior when a request is refused can be changed + to not deny but instead set an invalid <code>authentication</code> + header. This is useful in combination with the context attribute + <code>preemptiveAuthentication="true"</code>.</p> + <p><strong>Note:</strong> This filter processes the value returned by method <code>ServletRequest.getRemoteHost()</code>. To allow the method to return proper host names, you have to enable "DNS lookups" feature on @@ -629,6 +650,17 @@ request. The default value is <code>false</code>.</p> </attribute> + <attribute name="invalidAuthenticationWhenDeny" required="false"> + <p>When a request should be denied, do not deny but instead + set an invalid <code>authentication</code> header. This only works + if the context has the attribute <code>preemptiveAuthentication="true"</code> + set. An already existing <code>authentication</code> header will not be + overwritten. In effect this will trigger authentication instead of deny + even if the application does not have a security constraint configured.</p> + <p>This can be combined with <code>addLocalPort</code> to trigger authentication + depending on the client and the port that is used to access an application.</p> + </attribute> + </attributes> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org