1
0
mirror of synced 2026-08-05 17:57:15 +00:00

Make ChannelDecisionManagerImpl iterate through a list of channel security processors.

This commit is contained in:
Ben Alex
2004-04-29 02:17:07 +00:00
parent 2421268baa
commit ecac5a2eed
19 changed files with 1155 additions and 569 deletions
@@ -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.
*
* <P>
* 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}.
* </p>
*
* @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 this <code>ChannelDecisionManager</code> is able to
* process the passed <code>ConfigAttribute</code>.
*
* <p>
* This allows the <code>ChannelProcessingFilter</code> to check every
* configuration attribute can be consumed by the configured
* <code>ChannelDecisionManager</code>.
* </p>
*
* @param attribute a configuration attribute that has been configured
* against the <code>ChannelProcessingFilter</code>
*
* @return true if this <code>ChannelDecisionManager</code> can support the
* passed configuration attribute
*/
public boolean supports(ConfigAttribute attribute);
}
@@ -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}.
*
* <p>
* Ensures configuration attribute requested channel security is present by
* review of <code>HttpServletRequest.isSecure()</code> responses.
* Iterates through each configured {@link ChannelProcessor}. If a
* <code>ChannelProcessor</code> has any issue with the security of the
* request, it should cause a redirect, exception or whatever other action is
* appropriate for the <code>ChannelProcessor</code> implementation.
* </p>
*
* <P>
* The class responds to two and only two case-sensitive keywords: {@link
* #getInsecureKeyword()} and {@link #getSecureKeyword}. If either of these
* keywords are detected, <code>HttpServletRequest.isSecure()</code> is used
* to determine the channel security offered. If the channel security differs
* from that requested by the keyword, the relevant exception is thrown.
* </p>
*
* <P>
* If both the <code>secureKeyword</code> and <code>insecureKeyword</code>
* 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 <b>should</b> indicate one configuration attribute or the other
* (not both).
* </p>
*
* <P>
* The default <code>secureKeyword</code> and <code>insecureKeyword</code> is
* <code>REQUIRES_SECURE_CHANNEL</code> and
* <code>REQUIRES_INSECURE_CHANNEL</code> respectively.
* Once any response is committed (ie a redirect is written to the response
* object), the <code>ChannelDecisionManagerImpl</code> will not iterate
* through any further <code>ChannelProcessor</code>s.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class ChannelDecisionManagerImpl implements InitializingBean,
ChannelDecisionManager {
public class ChannelDecisionManagerImpl implements ChannelDecisionManager,
InitializingBean {
//~ Instance fields ========================================================
private String insecureKeyword = "REQUIRES_INSECURE_CHANNEL";
private String secureKeyword = "REQUIRES_SECURE_CHANNEL";
private List channelProcessors;
//~ Methods ================================================================
public void setInsecureKeyword(String insecureKeyword) {
this.insecureKeyword = insecureKeyword;
public void setChannelProcessors(List newList) {
checkIfValidList(newList);
Iterator iter = newList.iterator();
while (iter.hasNext()) {
Object currentObject = null;
try {
currentObject = iter.next();
ChannelProcessor attemptToCast = (ChannelProcessor) currentObject;
} catch (ClassCastException cce) {
throw new IllegalArgumentException("ChannelProcessor "
+ currentObject.getClass().getName()
+ " must implement ChannelProcessor");
}
}
this.channelProcessors = newList;
}
public String getInsecureKeyword() {
return insecureKeyword;
}
public void setSecureKeyword(String secureKeyword) {
this.secureKeyword = secureKeyword;
}
public String getSecureKeyword() {
return secureKeyword;
public List getChannelProcessors() {
return this.channelProcessors;
}
public void afterPropertiesSet() throws Exception {
if ((secureKeyword == null) || "".equals(secureKeyword)) {
throw new IllegalArgumentException("secureKeyword required");
}
if ((insecureKeyword == null) || "".equals(insecureKeyword)) {
throw new IllegalArgumentException("insecureKeyword required");
}
checkIfValidList(this.channelProcessors);
}
public void decide(FilterInvocation invocation,
ConfigAttributeDefinition config) throws SecureChannelRequiredException {
if ((invocation == null) || (config == null)) {
throw new IllegalArgumentException("Nulls cannot be provided");
}
Iterator iter = config.getConfigAttributes();
ConfigAttributeDefinition config) throws IOException, ServletException {
Iterator iter = this.channelProcessors.iterator();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
ChannelProcessor processor = (ChannelProcessor) iter.next();
if (attribute.equals(secureKeyword)) {
if (!invocation.getHttpRequest().isSecure()) {
throw new SecureChannelRequiredException(
"Request is not being made over a secure channel");
}
}
processor.decide(invocation, config);
if (attribute.equals(insecureKeyword)) {
if (invocation.getHttpRequest().isSecure()) {
throw new InsecureChannelRequiredException(
"Request is being made over a secure channel when an insecure channel is required");
}
if (invocation.getResponse().isCommitted()) {
break;
}
}
}
public boolean supports(ConfigAttribute attribute) {
Iterator iter = this.channelProcessors.iterator();
while (iter.hasNext()) {
ChannelProcessor processor = (ChannelProcessor) iter.next();
if (processor.supports(attribute)) {
return true;
}
}
return false;
}
private void checkIfValidList(List listToCheck) {
if ((listToCheck == null) || (listToCheck.size() == 0)) {
throw new IllegalArgumentException(
"A list of ChannelProcessors is required");
}
}
}
@@ -23,11 +23,13 @@ import javax.servlet.ServletResponse;
/**
* Used by {@link ChannelProcessingFilter} to launch a web channel.
* May be used by a {@link ChannelProcessor} to launch a web channel.
*
* <P>
* Depending on the implementation, a secure or insecure channel will be
* launched.
* <code>ChannelProcessor</code>s can elect to launch a new web channel
* directly, or they can delegate to another class. The
* <code>ChannelEntryPoint</code> is a pluggable interface to assist
* <code>ChannelProcessor</code>s in performing this delegation.
* </p>
*
* @author Ben Alex
@@ -42,13 +44,10 @@ public interface ChannelEntryPoint {
* <P>
* Implementations should modify the headers on the
* <code>ServletResponse</code> 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.
* </p>
*
* @param request that resulted in a
* <code>SecureChannelRequiredException</code> or
* <code>InsecureChannelRequiredException</code>
* @param request that a <code>ChannelProcessor</code> has rejected
* @param response so that the user agent can begin using a new channel
*/
public void commence(ServletRequest request, ServletResponse response)
@@ -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;
* </p>
*
* <P>
* Delegates the actual channel security decisions and necessary actions to the
* configured {@link ChannelDecisionManager}. If a response is committed by
* the <code>ChannelDecisionManager</code>, the filter chain will not proceed.
* </p>
*
* <P>
* <B>Do not use this class directly.</B> Instead configure
* <code>web.xml</code> 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;
}
}
@@ -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.
*
* <P>
* <code>ChannelProcessor</code> implementations are iterated by the {@link
* ChannelDecisionManagerImpl}.
* </p>
*
* <P>
* 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.
* </p>
*
* @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 this <code>ChannelProcessor</code> is able to process
* the passed <code>ConfigAttribute</code>.
*
* <p>
* This allows the <code>ChannelProcessingFilter</code> to check every
* configuration attribute can be consumed by the configured
* <code>ChannelDecisionManager</code>.
* </p>
*
* @param attribute a configuration attribute that has been configured
* against the <code>ChannelProcessingFilter</code>
*
* @return true if this <code>ChannelProcessor</code> can support the
* passed configuration attribute
*/
public boolean supports(ConfigAttribute attribute);
}
@@ -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;
/**
* <p>
* Ensures channel security is inactive by review of
* <code>HttpServletRequest.isSecure()</code> responses.
* </p>
*
* <P>
* The class responds to one case-sensitive keyword, {@link
* #getInsecureKeyword}. If this keyword is detected,
* <code>HttpServletRequest.isSecure()</code> is used to determine the channel
* security offered. If channel security is present, the configured
* <code>ChannelEntryPoint</code> is called. By default the entry point is
* {@link RetryWithHttpEntryPoint}.
* </p>
*
* <P>
* The default <code>insecureKeyword</code> is
* <code>REQUIRES_INSECURE_CHANNEL</code>.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class InsecureChannelProcessor implements InitializingBean,
ChannelProcessor {
//~ Instance fields ========================================================
private ChannelEntryPoint entryPoint = new RetryWithHttpEntryPoint();
private String insecureKeyword = "REQUIRES_INSECURE_CHANNEL";
//~ Methods ================================================================
public void setEntryPoint(ChannelEntryPoint entryPoint) {
this.entryPoint = entryPoint;
}
public ChannelEntryPoint getEntryPoint() {
return entryPoint;
}
public void setInsecureKeyword(String secureKeyword) {
this.insecureKeyword = secureKeyword;
}
public String getInsecureKeyword() {
return insecureKeyword;
}
public void afterPropertiesSet() throws Exception {
if ((insecureKeyword == null) || "".equals(insecureKeyword)) {
throw new IllegalArgumentException("insecureKeyword required");
}
if (entryPoint == null) {
throw new IllegalArgumentException("entryPoint required");
}
}
public void decide(FilterInvocation invocation,
ConfigAttributeDefinition config) throws IOException, ServletException {
if ((invocation == null) || (config == null)) {
throw new IllegalArgumentException("Nulls cannot be provided");
}
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (supports(attribute)) {
if (invocation.getHttpRequest().isSecure()) {
entryPoint.commence(invocation.getRequest(),
invocation.getResponse());
}
}
}
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute != null) && (attribute.getAttribute() != null)
&& attribute.getAttribute().equals(getInsecureKeyword())) {
return true;
} else {
return false;
}
}
}
@@ -1,50 +0,0 @@
/* 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.AccessDeniedException;
/**
* Thrown if a secure web channel is detected, but is not required.
*
* @author Ben Alex
* @version $Id$
*/
public class InsecureChannelRequiredException extends AccessDeniedException {
//~ Constructors ===========================================================
/**
* Constructs an <code>InsecureChannelRequiredException</code> with the
* specified message.
*
* @param msg the detail message.
*/
public InsecureChannelRequiredException(String msg) {
super(msg);
}
/**
* Constructs an <code>InsecureChannelRequiredException</code> 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);
}
}
@@ -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;
/**
* <p>
* Ensures channel security is active by review of
* <code>HttpServletRequest.isSecure()</code> responses.
* </p>
*
* <P>
* The class responds to one case-sensitive keyword, {@link #getSecureKeyword}.
* If this keyword is detected, <code>HttpServletRequest.isSecure()</code> is
* used to determine the channel security offered. If channel security is not
* present, the configured <code>ChannelEntryPoint</code> is called. By
* default the entry point is {@link RetryWithHttpsEntryPoint}.
* </p>
*
* <P>
* The default <code>secureKeyword</code> is
* <code>REQUIRES_SECURE_CHANNEL</code>.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class SecureChannelProcessor implements InitializingBean,
ChannelProcessor {
//~ Instance fields ========================================================
private ChannelEntryPoint entryPoint = new RetryWithHttpsEntryPoint();
private String secureKeyword = "REQUIRES_SECURE_CHANNEL";
//~ Methods ================================================================
public void setEntryPoint(ChannelEntryPoint entryPoint) {
this.entryPoint = entryPoint;
}
public ChannelEntryPoint getEntryPoint() {
return entryPoint;
}
public void setSecureKeyword(String secureKeyword) {
this.secureKeyword = secureKeyword;
}
public String getSecureKeyword() {
return secureKeyword;
}
public void afterPropertiesSet() throws Exception {
if ((secureKeyword == null) || "".equals(secureKeyword)) {
throw new IllegalArgumentException("secureKeyword required");
}
if (entryPoint == null) {
throw new IllegalArgumentException("entryPoint required");
}
}
public void decide(FilterInvocation invocation,
ConfigAttributeDefinition config) throws IOException, ServletException {
if ((invocation == null) || (config == null)) {
throw new IllegalArgumentException("Nulls cannot be provided");
}
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attribute = (ConfigAttribute) iter.next();
if (supports(attribute)) {
if (!invocation.getHttpRequest().isSecure()) {
entryPoint.commence(invocation.getRequest(),
invocation.getResponse());
}
}
}
}
public boolean supports(ConfigAttribute attribute) {
if ((attribute != null) && (attribute.getAttribute() != null)
&& attribute.getAttribute().equals(getSecureKeyword())) {
return true;
} else {
return false;
}
}
}
@@ -1,50 +0,0 @@
/* 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.AccessDeniedException;
/**
* Thrown if a secure web channel is required, but is not present.
*
* @author Ben Alex
* @version $Id$
*/
public class SecureChannelRequiredException extends AccessDeniedException {
//~ Constructors ===========================================================
/**
* Constructs a <code>SecureChannelRequiredException</code> with the
* specified message.
*
* @param msg the detail message.
*/
public SecureChannelRequiredException(String msg) {
super(msg);
}
/**
* Constructs a <code>SecureChannelRequiredException</code> 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);
}
}
@@ -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) {
@@ -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;
}
}
}
}
;
@@ -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) {
@@ -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")));
}
}
@@ -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")));
}
}