diff --git a/changelog.txt b/changelog.txt index 634de7cf23..c715c7a929 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,4 @@ -Changes in version 0.5 (2004-04-28) +Changes in version 0.5 (2004-04-29) ----------------------------------- * Added single sign on support via Yale Central Authentication Service (CAS) @@ -13,7 +13,7 @@ Changes in version 0.5 (2004-04-28) * Added definable prefixes to avoid expectation of "ROLE_" GrantedAuthoritys * Added pluggable AuthenticationEntryPoints to SecurityEnforcementFilter * Added Apache Ant path syntax support to SecurityEnforcementFilter -* Added filter to automate entry into secure channels, such as HTTPS +* Added filter to automate web channel requirements (eg HTTPS redirection) * Updated JAR to Spring 1.0.1 * Updated several classes to use absolute (not relative) redirection URLs * Refactored filters to use Spring application context lifecycle support diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java index 6547af3193..311ee5c489 100644 --- a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java +++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManager.java @@ -15,12 +15,23 @@ package net.sf.acegisecurity.securechannel; +import net.sf.acegisecurity.ConfigAttribute; import net.sf.acegisecurity.ConfigAttributeDefinition; import net.sf.acegisecurity.intercept.web.FilterInvocation; +import java.io.IOException; + +import javax.servlet.ServletException; + /** * Decides whether a web channel provides sufficient security. + * + *
+ * If necessary due to the nature of the redirection, implementations should + * store the original destination of the request in {@link + * net.sf.acegisecurity.ui.AbstractProcessingFilter#ACEGI_SECURITY_TARGET_URL_KEY}. + *
* * @author Ben Alex * @version $Id$ @@ -34,6 +45,23 @@ public interface ChannelDecisionManager { * ConfigAttributeDefinition}. */ public void decide(FilterInvocation invocation, - ConfigAttributeDefinition config) - throws InsecureChannelRequiredException, SecureChannelRequiredException; + ConfigAttributeDefinition config) throws IOException, ServletException; + + /** + * Indicates whether thisChannelDecisionManager
is able to
+ * process the passed ConfigAttribute
.
+ *
+ *
+ * This allows the ChannelProcessingFilter
to check every
+ * configuration attribute can be consumed by the configured
+ * ChannelDecisionManager
.
+ *
ChannelProcessingFilter
+ *
+ * @return true if this ChannelDecisionManager
can support the
+ * passed configuration attribute
+ */
+ public boolean supports(ConfigAttribute attribute);
}
diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java
index a2a93d0dce..a1277033ec 100644
--- a/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java
+++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelDecisionManagerImpl.java
@@ -21,100 +21,104 @@ import net.sf.acegisecurity.intercept.web.FilterInvocation;
import org.springframework.beans.factory.InitializingBean;
+import java.io.IOException;
+
import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletException;
/**
+ * Implementation of {@link ChannelDecisionManager}.
+ *
*
- * Ensures configuration attribute requested channel security is present by
- * review of HttpServletRequest.isSecure()
responses.
+ * Iterates through each configured {@link ChannelProcessor}. If a
+ * ChannelProcessor
has any issue with the security of the
+ * request, it should cause a redirect, exception or whatever other action is
+ * appropriate for the ChannelProcessor
implementation.
*
- * The class responds to two and only two case-sensitive keywords: {@link
- * #getInsecureKeyword()} and {@link #getSecureKeyword}. If either of these
- * keywords are detected, HttpServletRequest.isSecure()
is used
- * to determine the channel security offered. If the channel security differs
- * from that requested by the keyword, the relevant exception is thrown.
- *
- * If both the secureKeyword
and insecureKeyword
- * configuration attributes are detected, the request will be deemed to be
- * requesting a secure channel. This is a reasonable approach, as when in
- * doubt, the decision manager assumes the most secure outcome is desired. Of
- * course, you should indicate one configuration attribute or the other
- * (not both).
- *
- * The default secureKeyword
and insecureKeyword
is
- * REQUIRES_SECURE_CHANNEL
and
- * REQUIRES_INSECURE_CHANNEL
respectively.
+ * Once any response is committed (ie a redirect is written to the response
+ * object), the ChannelDecisionManagerImpl
will not iterate
+ * through any further ChannelProcessor
s.
*
- * Depending on the implementation, a secure or insecure channel will be
- * launched.
+ * ChannelProcessor
s can elect to launch a new web channel
+ * directly, or they can delegate to another class. The
+ * ChannelEntryPoint
is a pluggable interface to assist
+ * ChannelProcessor
s in performing this delegation.
*
* Implementations should modify the headers on the
* ServletResponse
as necessary to commence the user agent
- * using the implementation's supported channel type (ie secure or
- * insecure).
+ * using the implementation's supported channel type.
*
SecureChannelRequiredException
or
- * InsecureChannelRequiredException
+ * @param request that a ChannelProcessor
has rejected
* @param response so that the user agent can begin using a new channel
*/
public void commence(ServletRequest request, ServletResponse response)
diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java
index 8efef64f4c..92be0da303 100644
--- a/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java
+++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessingFilter.java
@@ -15,6 +15,7 @@
package net.sf.acegisecurity.securechannel;
+import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.intercept.web.FilterInvocation;
import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
@@ -26,6 +27,10 @@ import org.springframework.beans.factory.InitializingBean;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -46,6 +51,12 @@ import javax.servlet.http.HttpServletResponse;
*
*
*
+ * Delegates the actual channel security decisions and necessary actions to the
+ * configured {@link ChannelDecisionManager}. If a response is committed by
+ * the ChannelDecisionManager
, the filter chain will not proceed.
+ *
* Do not use this class directly. Instead configure
* web.xml
to use the {@link
* net.sf.acegisecurity.util.FilterToBeanProxy}.
@@ -62,8 +73,6 @@ public class ChannelProcessingFilter implements InitializingBean, Filter {
//~ Instance fields ========================================================
private ChannelDecisionManager channelDecisionManager;
- private ChannelEntryPoint insecureChannelEntryPoint;
- private ChannelEntryPoint secureChannelEntryPoint;
private FilterInvocationDefinitionSource filterInvocationDefinitionSource;
//~ Methods ================================================================
@@ -86,23 +95,6 @@ public class ChannelProcessingFilter implements InitializingBean, Filter {
return filterInvocationDefinitionSource;
}
- public void setInsecureChannelEntryPoint(
- ChannelEntryPoint insecureChannelEntryPoint) {
- this.insecureChannelEntryPoint = insecureChannelEntryPoint;
- }
-
- public ChannelEntryPoint getInsecureChannelEntryPoint() {
- return insecureChannelEntryPoint;
- }
-
- public void setSecureChannelEntryPoint(ChannelEntryPoint channelEntryPoint) {
- this.secureChannelEntryPoint = channelEntryPoint;
- }
-
- public ChannelEntryPoint getSecureChannelEntryPoint() {
- return secureChannelEntryPoint;
- }
-
public void afterPropertiesSet() throws Exception {
if (filterInvocationDefinitionSource == null) {
throw new IllegalArgumentException(
@@ -114,14 +106,41 @@ public class ChannelProcessingFilter implements InitializingBean, Filter {
"channelDecisionManager must be specified");
}
- if (secureChannelEntryPoint == null) {
- throw new IllegalArgumentException(
- "secureChannelEntryPoint must be specified");
+ Iterator iter = this.filterInvocationDefinitionSource
+ .getConfigAttributeDefinitions();
+
+ if (iter == null) {
+ if (logger.isWarnEnabled()) {
+ logger.warn(
+ "Could not validate configuration attributes as the FilterInvocationDefinitionSource did not return a ConfigAttributeDefinition Iterator");
+ }
+
+ return;
}
- if (insecureChannelEntryPoint == null) {
+ Set set = new HashSet();
+
+ while (iter.hasNext()) {
+ ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter
+ .next();
+ Iterator attributes = def.getConfigAttributes();
+
+ while (attributes.hasNext()) {
+ ConfigAttribute attr = (ConfigAttribute) attributes.next();
+
+ if (!this.channelDecisionManager.supports(attr)) {
+ set.add(attr);
+ }
+ }
+ }
+
+ if (set.size() == 0) {
+ if (logger.isInfoEnabled()) {
+ logger.info("Validated configuration attributes");
+ }
+ } else {
throw new IllegalArgumentException(
- "insecureChannelEntryPoint must be specified");
+ "Unsupported configuration attributes: " + set.toString());
}
}
@@ -147,27 +166,9 @@ public class ChannelProcessingFilter implements InitializingBean, Filter {
+ "; ConfigAttributes: " + attr.toString());
}
- try {
- channelDecisionManager.decide(fi, attr);
- } catch (SecureChannelRequiredException secureException) {
- if (logger.isDebugEnabled()) {
- logger.debug("Channel insufficient security ("
- + secureException.getMessage()
- + "); delegating to secureChannelEntryPoint");
- }
-
- secureChannelEntryPoint.commence(request, response);
-
- return;
- } catch (InsecureChannelRequiredException insecureException) {
- if (logger.isDebugEnabled()) {
- logger.debug("Channel too much security ("
- + insecureException.getMessage()
- + "); delegating to insecureChannelEntryPoint");
- }
-
- insecureChannelEntryPoint.commence(request, response);
+ channelDecisionManager.decide(fi, attr);
+ if (fi.getResponse().isCommitted()) {
return;
}
}
diff --git a/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessor.java b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessor.java
new file mode 100644
index 0000000000..82e072cb51
--- /dev/null
+++ b/core/src/main/java/org/acegisecurity/securechannel/ChannelProcessor.java
@@ -0,0 +1,72 @@
+/* Copyright 2004 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.securechannel;
+
+import net.sf.acegisecurity.ConfigAttribute;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.intercept.web.FilterInvocation;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+
+/**
+ * Decides whether a web channel meets a specific security condition.
+ *
+ *
+ * ChannelProcessor
implementations are iterated by the {@link
+ * ChannelDecisionManagerImpl}.
+ *
+ * If an implementation has an issue with the channel security, they should + * take action themselves. The callers of the implementation do not take any + * action. + *
+ * + * @author Ben Alex + * @version $Id$ + */ +public interface ChannelProcessor { + //~ Methods ================================================================ + + /** + * Decided whether the presented {@link FilterInvocation} provides the + * appropriate level of channel security based on the requested {@link + * ConfigAttributeDefinition}. + */ + public void decide(FilterInvocation invocation, + ConfigAttributeDefinition config) throws IOException, ServletException; + + /** + * Indicates whether thisChannelProcessor
is able to process
+ * the passed ConfigAttribute
.
+ *
+ *
+ * This allows the ChannelProcessingFilter
to check every
+ * configuration attribute can be consumed by the configured
+ * ChannelDecisionManager
.
+ *
ChannelProcessingFilter
+ *
+ * @return true if this ChannelProcessor
can support the
+ * passed configuration attribute
+ */
+ public boolean supports(ConfigAttribute attribute);
+}
diff --git a/core/src/main/java/org/acegisecurity/securechannel/InsecureChannelProcessor.java b/core/src/main/java/org/acegisecurity/securechannel/InsecureChannelProcessor.java
new file mode 100644
index 0000000000..23c2204c2d
--- /dev/null
+++ b/core/src/main/java/org/acegisecurity/securechannel/InsecureChannelProcessor.java
@@ -0,0 +1,117 @@
+/* Copyright 2004 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.securechannel;
+
+import net.sf.acegisecurity.ConfigAttribute;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.intercept.web.FilterInvocation;
+
+import org.springframework.beans.factory.InitializingBean;
+
+import java.io.IOException;
+
+import java.util.Iterator;
+
+import javax.servlet.ServletException;
+
+
+/**
+ *
+ * Ensures channel security is inactive by review of
+ * HttpServletRequest.isSecure()
responses.
+ *
+ * The class responds to one case-sensitive keyword, {@link
+ * #getInsecureKeyword}. If this keyword is detected,
+ * HttpServletRequest.isSecure()
is used to determine the channel
+ * security offered. If channel security is present, the configured
+ * ChannelEntryPoint
is called. By default the entry point is
+ * {@link RetryWithHttpEntryPoint}.
+ *
+ * The default insecureKeyword
is
+ * REQUIRES_INSECURE_CHANNEL
.
+ *
InsecureChannelRequiredException
with the
- * specified message.
- *
- * @param msg the detail message.
- */
- public InsecureChannelRequiredException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs an InsecureChannelRequiredException
with the
- * specified message and root cause.
- *
- * @param msg the detail message.
- * @param t root cause
- */
- public InsecureChannelRequiredException(String msg, Throwable t) {
- super(msg, t);
- }
-}
diff --git a/core/src/main/java/org/acegisecurity/securechannel/SecureChannelProcessor.java b/core/src/main/java/org/acegisecurity/securechannel/SecureChannelProcessor.java
new file mode 100644
index 0000000000..4c9367f43b
--- /dev/null
+++ b/core/src/main/java/org/acegisecurity/securechannel/SecureChannelProcessor.java
@@ -0,0 +1,116 @@
+/* Copyright 2004 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.securechannel;
+
+import net.sf.acegisecurity.ConfigAttribute;
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.intercept.web.FilterInvocation;
+
+import org.springframework.beans.factory.InitializingBean;
+
+import java.io.IOException;
+
+import java.util.Iterator;
+
+import javax.servlet.ServletException;
+
+
+/**
+ *
+ * Ensures channel security is active by review of
+ * HttpServletRequest.isSecure()
responses.
+ *
+ * The class responds to one case-sensitive keyword, {@link #getSecureKeyword}.
+ * If this keyword is detected, HttpServletRequest.isSecure()
is
+ * used to determine the channel security offered. If channel security is not
+ * present, the configured ChannelEntryPoint
is called. By
+ * default the entry point is {@link RetryWithHttpsEntryPoint}.
+ *
+ * The default secureKeyword
is
+ * REQUIRES_SECURE_CHANNEL
.
+ *
SecureChannelRequiredException
with the
- * specified message.
- *
- * @param msg the detail message.
- */
- public SecureChannelRequiredException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a SecureChannelRequiredException
with the
- * specified message and root cause.
- *
- * @param msg the detail message.
- * @param t root cause
- */
- public SecureChannelRequiredException(String msg, Throwable t) {
- super(msg, t);
- }
-}
diff --git a/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java b/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java
index 61c0db7f82..3112c05ebc 100644
--- a/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java
+++ b/core/src/test/java/org/acegisecurity/MockHttpServletResponse.java
@@ -56,7 +56,11 @@ public class MockHttpServletResponse implements HttpServletResponse {
}
public boolean isCommitted() {
- throw new UnsupportedOperationException("mock method not implemented");
+ if (redirect == null) {
+ return false;
+ } else {
+ return true;
+ }
}
public void setContentLength(int arg0) {
diff --git a/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java b/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java
index 96f748ea39..8395bb8c43 100644
--- a/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java
+++ b/core/src/test/java/org/acegisecurity/securechannel/ChannelDecisionManagerImplTests.java
@@ -17,6 +17,7 @@ package net.sf.acegisecurity.securechannel;
import junit.framework.TestCase;
+import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.MockFilterChain;
import net.sf.acegisecurity.MockHttpServletRequest;
@@ -24,6 +25,14 @@ import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.SecurityConfig;
import net.sf.acegisecurity.intercept.web.FilterInvocation;
+import java.io.IOException;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import javax.servlet.ServletException;
+
/**
* Tests {@link ChannelDecisionManagerImpl}.
@@ -42,141 +51,175 @@ public class ChannelDecisionManagerImplTests extends TestCase {
junit.textui.TestRunner.run(ChannelDecisionManagerImplTests.class);
}
- public void testDetectsInvalidInsecureKeyword() throws Exception {
+ public void testCannotSetEmptyChannelProcessorsList()
+ throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
- cdm.setInsecureKeyword("");
try {
- cdm.afterPropertiesSet();
+ cdm.setChannelProcessors(new Vector());
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
- assertEquals("insecureKeyword required", expected.getMessage());
- }
-
- cdm.setInsecureKeyword(null);
-
- try {
- cdm.afterPropertiesSet();
- fail("Should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- assertEquals("insecureKeyword required", expected.getMessage());
+ assertEquals("A list of ChannelProcessors is required",
+ expected.getMessage());
}
}
- public void testDetectsInvalidSecureKeyword() throws Exception {
+ public void testCannotSetIncorrectObjectTypesIntoChannelProcessorsList()
+ throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
- cdm.setSecureKeyword("");
+ List list = new Vector();
+ list.add("THIS IS NOT A CHANNELPROCESSOR");
try {
- cdm.afterPropertiesSet();
+ cdm.setChannelProcessors(list);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
- assertEquals("secureKeyword required", expected.getMessage());
- }
-
- cdm.setSecureKeyword(null);
-
- try {
- cdm.afterPropertiesSet();
- fail("Should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- assertEquals("secureKeyword required", expected.getMessage());
- }
- }
-
- public void testDetectsNullsPassedToMainMethod() {
- ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
-
- try {
- cdm.decide(null, new ConfigAttributeDefinition());
- fail("Should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- assertEquals("Nulls cannot be provided", expected.getMessage());
- }
-
- try {
- cdm.decide(new FilterInvocation(new MockHttpServletRequest("x"),
- new MockHttpServletResponse(), new MockFilterChain()), null);
- fail("Should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- assertEquals("Nulls cannot be provided", expected.getMessage());
- }
- }
-
- public void testDetectsWhenInsecureChannelNeededAndInsecureSchemeUsed() {
- ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
- attr.addConfigAttribute(new SecurityConfig(
- "SOME_CONFIG_ATTRIBUTE_TO_IGNORE"));
- attr.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
-
- MockHttpServletRequest request = new MockHttpServletRequest("foo=bar");
- request.setScheme("http");
-
- ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
- cdm.decide(new FilterInvocation(request, new MockHttpServletResponse(),
- new MockFilterChain()), attr);
- assertTrue(true);
- }
-
- public void testDetectsWhenInsecureChannelNeededAndSecureSchemeUsed() {
- ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
- attr.addConfigAttribute(new SecurityConfig(
- "SOME_CONFIG_ATTRIBUTE_TO_IGNORE"));
- attr.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
-
- MockHttpServletRequest request = new MockHttpServletRequest("foo=bar");
- request.setScheme("https");
-
- ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
-
- try {
- cdm.decide(new FilterInvocation(request,
- new MockHttpServletResponse(), new MockFilterChain()), attr);
- } catch (InsecureChannelRequiredException expected) {
assertTrue(true);
}
}
- public void testDetectsWhenSecureChannelNeeded() {
- ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
- attr.addConfigAttribute(new SecurityConfig(
- "SOME_CONFIG_ATTRIBUTE_TO_IGNORE"));
- attr.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
-
- MockHttpServletRequest request = new MockHttpServletRequest("foo=bar");
- request.setScheme("http");
-
+ public void testCannotSetNullChannelProcessorsList()
+ throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
try {
- cdm.decide(new FilterInvocation(request,
- new MockHttpServletResponse(), new MockFilterChain()), attr);
- } catch (SecureChannelRequiredException expected) {
- assertTrue(true);
+ cdm.setChannelProcessors(null);
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("A list of ChannelProcessors is required",
+ expected.getMessage());
}
}
- public void testGetterSetters() throws Exception {
+ public void testDecideIsOperational() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
+ MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
+ MockChannelProcessor cpAbc = new MockChannelProcessor("abc", true);
+ List list = new Vector();
+ list.add(cpXyz);
+ list.add(cpAbc);
+ cdm.setChannelProcessors(list);
cdm.afterPropertiesSet();
- assertEquals("REQUIRES_INSECURE_CHANNEL", cdm.getInsecureKeyword());
- assertEquals("REQUIRES_SECURE_CHANNEL", cdm.getSecureKeyword());
- cdm.setInsecureKeyword("MY_INSECURE");
- cdm.setSecureKeyword("MY_SECURE");
+ MockHttpServletRequest request = new MockHttpServletRequest("not used");
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain();
+ FilterInvocation fi = new FilterInvocation(request, response, chain);
- assertEquals("MY_INSECURE", cdm.getInsecureKeyword());
- assertEquals("MY_SECURE", cdm.getSecureKeyword());
+ ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
+ cad.addConfigAttribute(new SecurityConfig("xyz"));
+
+ cdm.decide(fi, cad);
+ assertTrue(fi.getResponse().isCommitted());
}
- public void testIgnoresOtherConfigAttributes() {
- ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
- attr.addConfigAttribute(new SecurityConfig("XYZ"));
-
+ public void testDecideIteratesAllProcessorsIfNoneCommitAResponse()
+ throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
- cdm.decide(new FilterInvocation(new MockHttpServletRequest("x"),
- new MockHttpServletResponse(), new MockFilterChain()), attr);
- assertTrue(true);
+ MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
+ MockChannelProcessor cpAbc = new MockChannelProcessor("abc", false);
+ List list = new Vector();
+ list.add(cpXyz);
+ list.add(cpAbc);
+ cdm.setChannelProcessors(list);
+ cdm.afterPropertiesSet();
+
+ MockHttpServletRequest request = new MockHttpServletRequest("not used");
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain();
+ FilterInvocation fi = new FilterInvocation(request, response, chain);
+
+ ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
+ cad.addConfigAttribute(new SecurityConfig(
+ "SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT"));
+
+ cdm.decide(fi, cad);
+ assertFalse(fi.getResponse().isCommitted());
+ }
+
+ public void testDelegatesSupports() throws Exception {
+ ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
+ MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
+ MockChannelProcessor cpAbc = new MockChannelProcessor("abc", false);
+ List list = new Vector();
+ list.add(cpXyz);
+ list.add(cpAbc);
+ cdm.setChannelProcessors(list);
+ cdm.afterPropertiesSet();
+
+ assertTrue(cdm.supports(new SecurityConfig("xyz")));
+ assertTrue(cdm.supports(new SecurityConfig("abc")));
+ assertFalse(cdm.supports(new SecurityConfig("UNSUPPORTED")));
+ }
+
+ public void testGettersSetters() {
+ ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
+ assertNull(cdm.getChannelProcessors());
+
+ MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
+ MockChannelProcessor cpAbc = new MockChannelProcessor("abc", false);
+ List list = new Vector();
+ list.add(cpXyz);
+ list.add(cpAbc);
+ cdm.setChannelProcessors(list);
+
+ assertEquals(list, cdm.getChannelProcessors());
+ }
+
+ public void testStartupFailsWithEmptyChannelProcessorsList()
+ throws Exception {
+ ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
+
+ try {
+ cdm.afterPropertiesSet();
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("A list of ChannelProcessors is required",
+ expected.getMessage());
+ }
+ }
+
+ //~ Inner Classes ==========================================================
+
+ private class MockChannelProcessor implements ChannelProcessor {
+ private String configAttribute;
+ private boolean failIfCalled;
+
+ public MockChannelProcessor(String configAttribute, boolean failIfCalled) {
+ this.configAttribute = configAttribute;
+ this.failIfCalled = failIfCalled;
+ }
+
+ private MockChannelProcessor() {
+ super();
+ }
+
+ public void decide(FilterInvocation invocation,
+ ConfigAttributeDefinition config)
+ throws IOException, ServletException {
+ Iterator iter = config.getConfigAttributes();
+
+ if (failIfCalled) {
+ fail("Should not have called this channel processor");
+ }
+
+ while (iter.hasNext()) {
+ ConfigAttribute attr = (ConfigAttribute) iter.next();
+
+ if (attr.equals(configAttribute)) {
+ invocation.getHttpResponse().sendRedirect("/redirected");
+
+ return;
+ }
+ }
+ }
+
+ public boolean supports(ConfigAttribute attribute) {
+ if (attribute.getAttribute().equals(configAttribute)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
}
}
-;
diff --git a/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java
index 0f962b615d..d79f0d14c6 100644
--- a/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java
+++ b/core/src/test/java/org/acegisecurity/securechannel/ChannelProcessingFilterTests.java
@@ -17,18 +17,19 @@ package net.sf.acegisecurity.securechannel;
import junit.framework.TestCase;
+import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;
-import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.SecurityConfig;
import net.sf.acegisecurity.intercept.web.FilterInvocation;
import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
-import net.sf.acegisecurity.intercept.web.RegExpBasedFilterInvocationDefinitionMap;
import java.io.IOException;
import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
@@ -53,61 +54,16 @@ public class ChannelProcessingFilterTests extends TestCase {
junit.textui.TestRunner.run(ChannelProcessingFilterTests.class);
}
- public void testCallsInsecureEntryPointWhenTooMuchChannelSecurity()
- throws Exception {
- ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
- attr.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
-
- MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
- attr);
-
- ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new MockEntryPoint(true));
- filter.setSecureChannelEntryPoint(new MockEntryPoint(false));
- filter.setFilterInvocationDefinitionSource(fids);
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
-
- MockHttpServletRequest request = new MockHttpServletRequest("info=now");
- request.setServletPath("/path");
- request.setScheme("https");
-
- MockHttpServletResponse response = new MockHttpServletResponse();
- MockFilterChain chain = new MockFilterChain(false);
-
- filter.doFilter(request, response, chain);
- assertTrue(true);
- }
-
- public void testCallsSecureEntryPointWhenTooLittleChannelSecurity()
- throws Exception {
- ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
- attr.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
-
- MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
- attr);
-
- ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new MockEntryPoint(false));
- filter.setSecureChannelEntryPoint(new MockEntryPoint(true));
- filter.setFilterInvocationDefinitionSource(fids);
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
-
- MockHttpServletRequest request = new MockHttpServletRequest("info=now");
- request.setServletPath("/path");
- request.setScheme("http");
-
- MockHttpServletResponse response = new MockHttpServletResponse();
- MockFilterChain chain = new MockFilterChain(false);
-
- filter.doFilter(request, response, chain);
- assertTrue(true);
- }
-
public void testDetectsMissingChannelDecisionManager()
throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
- filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
+
+ ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
+ attr.addConfigAttribute(new SecurityConfig("MOCK"));
+
+ MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
+ attr, true);
+ filter.setFilterInvocationDefinitionSource(fids);
try {
filter.afterPropertiesSet();
@@ -118,12 +74,11 @@ public class ChannelProcessingFilterTests extends TestCase {
}
}
- public void testDetectsMissingFilterInvocationDefinitionMap()
+ public void testDetectsMissingFilterInvocationDefinitionSource()
throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
- filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
+ filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
+ "MOCK"));
try {
filter.afterPropertiesSet();
@@ -134,36 +89,116 @@ public class ChannelProcessingFilterTests extends TestCase {
}
}
- public void testDetectsMissingInsecureChannelEntryPoint()
+ public void testDetectsSupportedConfigAttribute() throws Exception {
+ ChannelProcessingFilter filter = new ChannelProcessingFilter();
+ filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
+ "SUPPORTS_MOCK_ONLY"));
+
+ ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
+ attr.addConfigAttribute(new SecurityConfig("SUPPORTS_MOCK_ONLY"));
+
+ MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
+ attr, true);
+
+ filter.setFilterInvocationDefinitionSource(fids);
+
+ filter.afterPropertiesSet();
+ assertTrue(true);
+ }
+
+ public void testDetectsUnsupportedConfigAttribute()
throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
- filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
+ filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
+ "SUPPORTS_MOCK_ONLY"));
+
+ ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
+ attr.addConfigAttribute(new SecurityConfig("SUPPORTS_MOCK_ONLY"));
+ attr.addConfigAttribute(new SecurityConfig("INVALID_ATTRIBUTE"));
+
+ MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
+ attr, true);
+
+ filter.setFilterInvocationDefinitionSource(fids);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
- assertEquals("insecureChannelEntryPoint must be specified",
- expected.getMessage());
+ assertTrue(expected.getMessage().startsWith("Unsupported configuration attributes:"));
}
}
- public void testDetectsMissingSecureChannelEntryPoint()
+ public void testDoFilterWhenManagerDoesCommitResponse()
throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
- filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
+ filter.setChannelDecisionManager(new MockChannelDecisionManager(true,
+ "SOME_ATTRIBUTE"));
- try {
- filter.afterPropertiesSet();
- fail("Should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- assertEquals("secureChannelEntryPoint must be specified",
- expected.getMessage());
- }
+ ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
+ attr.addConfigAttribute(new SecurityConfig("SOME_ATTRIBUTE"));
+
+ MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
+ attr, true);
+
+ filter.setFilterInvocationDefinitionSource(fids);
+
+ MockHttpServletRequest request = new MockHttpServletRequest("info=now");
+ request.setServletPath("/path");
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain(false);
+
+ filter.doFilter(request, response, chain);
+ assertTrue(true);
+ }
+
+ public void testDoFilterWhenManagerDoesNotCommitResponse()
+ throws Exception {
+ ChannelProcessingFilter filter = new ChannelProcessingFilter();
+ filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
+ "SOME_ATTRIBUTE"));
+
+ ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
+ attr.addConfigAttribute(new SecurityConfig("SOME_ATTRIBUTE"));
+
+ MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
+ attr, true);
+
+ filter.setFilterInvocationDefinitionSource(fids);
+
+ MockHttpServletRequest request = new MockHttpServletRequest("info=now");
+ request.setServletPath("/path");
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain(true);
+
+ filter.doFilter(request, response, chain);
+ assertTrue(true);
+ }
+
+ public void testDoFilterWhenNullConfigAttributeReturned()
+ throws Exception {
+ ChannelProcessingFilter filter = new ChannelProcessingFilter();
+ filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
+ "NOT_USED"));
+
+ ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
+ attr.addConfigAttribute(new SecurityConfig("NOT_USED"));
+
+ MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
+ attr, true);
+
+ filter.setFilterInvocationDefinitionSource(fids);
+
+ MockHttpServletRequest request = new MockHttpServletRequest("info=now");
+ request.setServletPath("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE");
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain(true);
+
+ filter.doFilter(request, response, chain);
+ assertTrue(true);
}
public void testDoFilterWithNonHttpServletRequestDetected()
@@ -192,91 +227,55 @@ public class ChannelProcessingFilterTests extends TestCase {
}
}
- public void testDoesNotInterruptRequestsWithCorrectChannelSecurity()
- throws Exception {
+ public void testGetterSetters() throws Exception {
+ ChannelProcessingFilter filter = new ChannelProcessingFilter();
+ filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
+ "MOCK"));
+ assertTrue(filter.getChannelDecisionManager() != null);
+
ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
- attr.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
+ attr.addConfigAttribute(new SecurityConfig("MOCK"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
- attr);
+ attr, false);
- ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
- filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
filter.setFilterInvocationDefinitionSource(fids);
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
-
- MockHttpServletRequest request = new MockHttpServletRequest("info=now");
- request.setServletPath("/path");
- request.setScheme("https");
-
- MockHttpServletResponse response = new MockHttpServletResponse();
- MockFilterChain chain = new MockFilterChain(true);
-
- filter.doFilter(request, response, chain);
- assertTrue(true);
- }
-
- public void testDoesNotInterruptRequestsWithNoConfigAttribute()
- throws Exception {
- ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
- filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
- filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
-
- MockHttpServletRequest request = new MockHttpServletRequest("info=now");
- MockHttpServletResponse response = new MockHttpServletResponse();
- MockFilterChain chain = new MockFilterChain(true);
-
- filter.doFilter(request, response, chain);
- assertTrue(true);
- }
-
- public void testGetterSetters() {
- ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
- filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
- filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
-
- assertTrue(filter.getInsecureChannelEntryPoint() != null);
- assertTrue(filter.getSecureChannelEntryPoint() != null);
assertTrue(filter.getFilterInvocationDefinitionSource() != null);
- assertTrue(filter.getChannelDecisionManager() != null);
- }
- public void testLifecycle() throws Exception {
- ChannelProcessingFilter filter = new ChannelProcessingFilter();
- filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
- filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
- filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
- filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
+ filter.init(null);
filter.afterPropertiesSet();
-
- filter.init(new MockFilterConfig());
filter.destroy();
}
//~ Inner Classes ==========================================================
- private class MockEntryPoint implements ChannelEntryPoint {
- private boolean expectToBeCalled;
+ private class MockChannelDecisionManager implements ChannelDecisionManager {
+ private String supportAttribute;
+ private boolean commitAResponse;
- public MockEntryPoint(boolean expectToBeCalled) {
- this.expectToBeCalled = expectToBeCalled;
+ public MockChannelDecisionManager(boolean commitAResponse,
+ String supportAttribute) {
+ this.commitAResponse = commitAResponse;
+ this.supportAttribute = supportAttribute;
}
- private MockEntryPoint() {
+ private MockChannelDecisionManager() {
super();
}
- public void commence(ServletRequest request, ServletResponse response)
+ public void decide(FilterInvocation invocation,
+ ConfigAttributeDefinition config)
throws IOException, ServletException {
- if (expectToBeCalled) {
- assertTrue(true);
+ if (commitAResponse) {
+ invocation.getHttpResponse().sendRedirect("/redirected");
+ }
+ }
+
+ public boolean supports(ConfigAttribute attribute) {
+ if (attribute.getAttribute().equals(supportAttribute)) {
+ return true;
} else {
- fail("Did not expect this ChannelEntryPoint to be called");
+ return false;
}
}
}
@@ -306,11 +305,13 @@ public class ChannelProcessingFilterTests extends TestCase {
implements FilterInvocationDefinitionSource {
private ConfigAttributeDefinition toReturn;
private String servletPath;
+ private boolean provideIterator;
public MockFilterInvocationDefinitionMap(String servletPath,
- ConfigAttributeDefinition toReturn) {
+ ConfigAttributeDefinition toReturn, boolean provideIterator) {
this.servletPath = servletPath;
this.toReturn = toReturn;
+ this.provideIterator = provideIterator;
}
private MockFilterInvocationDefinitionMap() {
@@ -329,7 +330,14 @@ public class ChannelProcessingFilterTests extends TestCase {
}
public Iterator getConfigAttributeDefinitions() {
- return null;
+ if (!provideIterator) {
+ return null;
+ }
+
+ List list = new Vector();
+ list.add(toReturn);
+
+ return list.iterator();
}
public boolean supports(Class clazz) {
diff --git a/core/src/test/java/org/acegisecurity/securechannel/InsecureChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/securechannel/InsecureChannelProcessorTests.java
new file mode 100644
index 0000000000..329341c8a4
--- /dev/null
+++ b/core/src/test/java/org/acegisecurity/securechannel/InsecureChannelProcessorTests.java
@@ -0,0 +1,153 @@
+/* Copyright 2004 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.securechannel;
+
+import junit.framework.TestCase;
+
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.MockFilterChain;
+import net.sf.acegisecurity.MockHttpServletRequest;
+import net.sf.acegisecurity.MockHttpServletResponse;
+import net.sf.acegisecurity.SecurityConfig;
+import net.sf.acegisecurity.intercept.web.FilterInvocation;
+
+
+/**
+ * Tests {@link InsecureChannelProcessor}.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class InsecureChannelProcessorTests extends TestCase {
+ //~ Methods ================================================================
+
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(InsecureChannelProcessorTests.class);
+ }
+
+ public void testDecideDetectsAcceptableChannel() throws Exception {
+ ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
+ cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE"));
+ cad.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
+
+ MockHttpServletRequest request = new MockHttpServletRequest("info=true");
+ request.setServerName("localhost");
+ request.setContextPath("/bigapp");
+ request.setServletPath("/servlet");
+ request.setScheme("http");
+ request.setServerPort(8080);
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain();
+ FilterInvocation fi = new FilterInvocation(request, response, chain);
+
+ InsecureChannelProcessor processor = new InsecureChannelProcessor();
+ processor.decide(fi, cad);
+
+ assertFalse(fi.getResponse().isCommitted());
+ }
+
+ public void testDecideDetectsUnacceptableChannel()
+ throws Exception {
+ ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
+ cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE"));
+ cad.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
+
+ MockHttpServletRequest request = new MockHttpServletRequest("info=true");
+ request.setServerName("localhost");
+ request.setContextPath("/bigapp");
+ request.setServletPath("/servlet");
+ request.setScheme("https");
+ request.setServerPort(8443);
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain();
+ FilterInvocation fi = new FilterInvocation(request, response, chain);
+
+ InsecureChannelProcessor processor = new InsecureChannelProcessor();
+ processor.decide(fi, cad);
+
+ assertTrue(fi.getResponse().isCommitted());
+ }
+
+ public void testDecideRejectsNulls() throws Exception {
+ InsecureChannelProcessor processor = new InsecureChannelProcessor();
+ processor.afterPropertiesSet();
+
+ try {
+ processor.decide(null, null);
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(true);
+ }
+ }
+
+ public void testGettersSetters() {
+ InsecureChannelProcessor processor = new InsecureChannelProcessor();
+ assertEquals("REQUIRES_INSECURE_CHANNEL", processor.getInsecureKeyword());
+ processor.setInsecureKeyword("X");
+ assertEquals("X", processor.getInsecureKeyword());
+
+ assertTrue(processor.getEntryPoint() != null);
+ processor.setEntryPoint(null);
+ assertTrue(processor.getEntryPoint() == null);
+ }
+
+ public void testMissingEntryPoint() throws Exception {
+ InsecureChannelProcessor processor = new InsecureChannelProcessor();
+ processor.setEntryPoint(null);
+
+ try {
+ processor.afterPropertiesSet();
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("entryPoint required", expected.getMessage());
+ }
+ }
+
+ public void testMissingSecureChannelKeyword() throws Exception {
+ InsecureChannelProcessor processor = new InsecureChannelProcessor();
+ processor.setInsecureKeyword(null);
+
+ try {
+ processor.afterPropertiesSet();
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("insecureKeyword required", expected.getMessage());
+ }
+
+ processor.setInsecureKeyword("");
+
+ try {
+ processor.afterPropertiesSet();
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("insecureKeyword required", expected.getMessage());
+ }
+ }
+
+ public void testSupports() {
+ InsecureChannelProcessor processor = new InsecureChannelProcessor();
+ assertTrue(processor.supports(
+ new SecurityConfig("REQUIRES_INSECURE_CHANNEL")));
+ assertFalse(processor.supports(null));
+ assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
+ }
+}
diff --git a/core/src/test/java/org/acegisecurity/securechannel/SecureChannelProcessorTests.java b/core/src/test/java/org/acegisecurity/securechannel/SecureChannelProcessorTests.java
new file mode 100644
index 0000000000..b643228d3a
--- /dev/null
+++ b/core/src/test/java/org/acegisecurity/securechannel/SecureChannelProcessorTests.java
@@ -0,0 +1,153 @@
+/* Copyright 2004 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.sf.acegisecurity.securechannel;
+
+import junit.framework.TestCase;
+
+import net.sf.acegisecurity.ConfigAttributeDefinition;
+import net.sf.acegisecurity.MockFilterChain;
+import net.sf.acegisecurity.MockHttpServletRequest;
+import net.sf.acegisecurity.MockHttpServletResponse;
+import net.sf.acegisecurity.SecurityConfig;
+import net.sf.acegisecurity.intercept.web.FilterInvocation;
+
+
+/**
+ * Tests {@link SecureChannelProcessor}.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public class SecureChannelProcessorTests extends TestCase {
+ //~ Methods ================================================================
+
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(SecureChannelProcessorTests.class);
+ }
+
+ public void testDecideDetectsAcceptableChannel() throws Exception {
+ ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
+ cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE"));
+ cad.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
+
+ MockHttpServletRequest request = new MockHttpServletRequest("info=true");
+ request.setServerName("localhost");
+ request.setContextPath("/bigapp");
+ request.setServletPath("/servlet");
+ request.setScheme("https");
+ request.setServerPort(8443);
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain();
+ FilterInvocation fi = new FilterInvocation(request, response, chain);
+
+ SecureChannelProcessor processor = new SecureChannelProcessor();
+ processor.decide(fi, cad);
+
+ assertFalse(fi.getResponse().isCommitted());
+ }
+
+ public void testDecideDetectsUnacceptableChannel()
+ throws Exception {
+ ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
+ cad.addConfigAttribute(new SecurityConfig("SOME_IGNORED_ATTRIBUTE"));
+ cad.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
+
+ MockHttpServletRequest request = new MockHttpServletRequest("info=true");
+ request.setServerName("localhost");
+ request.setContextPath("/bigapp");
+ request.setServletPath("/servlet");
+ request.setScheme("http");
+ request.setServerPort(8080);
+
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ MockFilterChain chain = new MockFilterChain();
+ FilterInvocation fi = new FilterInvocation(request, response, chain);
+
+ SecureChannelProcessor processor = new SecureChannelProcessor();
+ processor.decide(fi, cad);
+
+ assertTrue(fi.getResponse().isCommitted());
+ }
+
+ public void testDecideRejectsNulls() throws Exception {
+ SecureChannelProcessor processor = new SecureChannelProcessor();
+ processor.afterPropertiesSet();
+
+ try {
+ processor.decide(null, null);
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertTrue(true);
+ }
+ }
+
+ public void testGettersSetters() {
+ SecureChannelProcessor processor = new SecureChannelProcessor();
+ assertEquals("REQUIRES_SECURE_CHANNEL", processor.getSecureKeyword());
+ processor.setSecureKeyword("X");
+ assertEquals("X", processor.getSecureKeyword());
+
+ assertTrue(processor.getEntryPoint() != null);
+ processor.setEntryPoint(null);
+ assertTrue(processor.getEntryPoint() == null);
+ }
+
+ public void testMissingEntryPoint() throws Exception {
+ SecureChannelProcessor processor = new SecureChannelProcessor();
+ processor.setEntryPoint(null);
+
+ try {
+ processor.afterPropertiesSet();
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("entryPoint required", expected.getMessage());
+ }
+ }
+
+ public void testMissingSecureChannelKeyword() throws Exception {
+ SecureChannelProcessor processor = new SecureChannelProcessor();
+ processor.setSecureKeyword(null);
+
+ try {
+ processor.afterPropertiesSet();
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("secureKeyword required", expected.getMessage());
+ }
+
+ processor.setSecureKeyword("");
+
+ try {
+ processor.afterPropertiesSet();
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("secureKeyword required", expected.getMessage());
+ }
+ }
+
+ public void testSupports() {
+ SecureChannelProcessor processor = new SecureChannelProcessor();
+ assertTrue(processor.supports(
+ new SecurityConfig("REQUIRES_SECURE_CHANNEL")));
+ assertFalse(processor.supports(null));
+ assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
+ }
+}
diff --git a/docs/reference/src/index.xml b/docs/reference/src/index.xml
index 3f2590ec33..a7dedc2386 100644
--- a/docs/reference/src/index.xml
+++ b/docs/reference/src/index.xml
@@ -522,20 +522,17 @@
Acegi Security System for Spring use this class. Refer to the Filters
section to learn more about this bean.
-