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

View File

@ -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

View File

@ -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);
}

View File

@ -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");
}
}
}

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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;
}
}
}
}
;

View File

@ -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) {

View File

@ -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")));
}
}

View File

@ -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")));
}
}

View File

@ -522,20 +522,17 @@
Acegi Security System for Spring use this class. Refer to the Filters
section to learn more about this bean.</para>
<para>In the application context you will need to configure four
<para>In the application context you will need to configure three
beans:</para>
<programlisting>&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
&lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
&lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;
&lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
&lt;property name="forceHttps"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;property name="portMapper"&gt;&lt;ref bean="portMapper"/&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
@ -549,12 +546,6 @@
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;!-- Comment the always[Scheme]Port properties to use ServletRequest.getServerPort() --&gt;
&lt;bean id="portResolver" class="net.sf.acegisecurity.util.PortResolverImpl"&gt;
&lt;property name="alwaysHttpPort"&gt;&lt;value&gt;8080&lt;/value&gt;&lt;/property&gt;
&lt;property name="alwaysHttpsPort"&gt;&lt;value&gt;8443&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>The <literal>AuthenticationEntryPoint</literal> will be called
@ -573,13 +564,6 @@
properties related to forcing the use of HTTPS, so please refer to the
JavaDocs if you require this.</para>
<para>The <literal>PortResolver</literal> is used to inspect a HTTP
request and determine the server port it was received on. Generally
this means using <literal>ServletRequest.getServerPort()</literal>,
although implementations can be forced to always return particular
ports (based on the transport protocol), as shown in the example
above. </para>
<para>The <literal>PortMapper</literal> provides information on which
HTTPS ports correspond to which HTTP ports. This is used by the
<literal>AuthenticationProcessingFilterEntryPoint</literal> and
@ -2756,10 +2740,12 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<para>In addition to coordinating the authentication and authorization
requirements of your application, the Acegi Security System for Spring
is also able to ensure web requests are received using an appropriate
transport. If your application has many security requirements, you'll
probably want to use HTTPS as the transport, whilst less secure pages
can use the unencrypted HTTP transport.</para>
is also able to ensure unauthenticated web requests have certain
properties. These properties may include being of a particular
transport type, having a particular <literal>HttpSession</literal>
attribute set and so on. The most common requirement is for your web
requests to be received using a particular transport protocol, such as
HTTPS.</para>
<para>An important issue in considering transport security is that of
session hijacking. Your web container manages a
@ -2809,30 +2795,28 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<para><programlisting>&lt;bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter"&gt;
&lt;property name="channelDecisionManager"&gt;&lt;ref bean="channelDecisionManager"/&gt;&lt;/property&gt;
&lt;property name="secureChannelEntryPoint"&gt;&lt;ref bean="secureChannelEntryPoint"/&gt;&lt;/property&gt;
&lt;property name="insecureChannelEntryPoint"&gt;&lt;ref bean="insecureChannelEntryPoint"/&gt;&lt;/property&gt;
&lt;property name="filterInvocationDefinitionSource"&gt;
&lt;value&gt;
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
\A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
\A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
\A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
\A.*\Z=REQUIRES_INSECURE_CHANNEL
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/&gt;
&lt;bean id="secureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint"&gt;
&lt;property name="portMapper"&gt;&lt;ref bean="portMapper"/&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"&gt;
&lt;property name="channelProcessors"&gt;
&lt;list&gt;
&lt;ref bean="secureChannelProcessor"/&gt;
&lt;ref bean="insecureChannelProcessor"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="insecureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint"&gt;
&lt;property name="portMapper"&gt;&lt;ref bean="portMapper"/&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
&lt;bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/&gt;
&lt;bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/&gt;</programlisting></para>
<para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
style paths are also supported by the
@ -2843,36 +2827,41 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
attributes that apply. It then delegates to the
<literal>ChannelDecisionManager</literal>. The default implementation,
<literal>ChannelDecisionManagerImpl</literal>, should suffice in most
cases. It simply throws a
<literal>SecureChannelRequiredException</literal> or
<literal>InsecureChannelRequiredException</literal> if the request's
transport channel carries too little or too much security
respectively. </para>
cases. It simply delegates through the list of configured
<literal>ChannelProcessor</literal> instances. A
<literal>ChannelProcessor</literal> will review the request, and if it
is unhappy with the request (eg it was received across the incorrect
transport protocol), it will perform a redirect, throw an exception or
take whatever other action is appropriate.</para>
<para>The <literal>ChannelProcessingFilter</literal> will detect the
<literal>SecureChannelRequiredException</literal> or
<literal>InsecureChannelRequiredException</literal> and delegate to
the <literal>secureChannelEntryPoint</literal> or
<literal>insecureChannelEntryPoint</literal> respectively. These entry
points implement the <literal>ChannelEntryPoint</literal> interface,
which allows the implementation to perform a redirect or take similar
action. The included <literal>RetryWithHttpsEntryPoint</literal> and
<literal>RetryWithHttpEntryPoint</literal> implementations simply
perform a redirect.</para>
<para>Included with the Acegi Security System for Spring are two
concrete <literal>ChannelProcessor</literal> implementations:
<literal>SecureChannelProcessor</literal> ensures requests with a
configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
are received over HTTPS, whilst
<literal>InsecureChannelProcessor</literal> ensures requests with a
configuration attribute of
<literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
Both implementations delegate to a
<literal>ChannelEntryPoint</literal> if the required transport
protocol is not used. The two <literal>ChannelEntryPoint</literal>
implementations included with Acegi Security simply redirect the
request to HTTP and HTTPS as appropriate. Appropriate defaults are
assigned to the <literal>ChannelProcessor</literal> implementations
for the configuration attribute keywords they respond to and the
<literal>ChannelEntryPoint</literal> they delegate to, although you
have the ability to override these using the application
context.</para>
<para>Note that the redirections are absolute (eg
http://www.company.com:8080/app/page), not relative (eg /app/page).
During testing it was discovered that Internet Explorer 6 Service Pack
1 appears to have a bug whereby it does not respond correctly to a
redirection instruction which also changes the port to use.
Accordingly, absolute URLs are used in conjunction with the
<literal>PortResolver</literal> interface to overcome this issue. The
<literal>PortResolverImpl</literal> is the included implementation,
and is capable of determining the port a request was received on
either from the <literal>ServletRequest.getServerPort()</literal>
method or from properties defined in the application context. Please
refer to the JavaDocs for <literal>PortResolverImpl</literal> for
further details.</para>
1 has a bug whereby it does not respond correctly to a redirection
instruction which also changes the port to use. Accordingly, absolute
URLs are used in conjunction with bug detection logic in the
<literal>PortResolverImpl</literal> that is wired up by default to
many Acegi Security beans. Please refer to the JavaDocs for
<literal>PortResolverImpl</literal> for further details.</para>
</sect2>
<sect2 id="security-channels-usage">
@ -2885,6 +2874,29 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<literal>web.xml</literal> <literal>&lt;welcome-file&gt;</literal> or
a well-known home page URL), but once this is done the filter will
perform redirects as defined by your application context.</para>
<para>You can also add your own <literal>ChannelProcessor</literal>
implementations to the <literal>ChannelDecisionManagerImpl</literal>.
For example, you might set a <literal>HttpSession</literal> attribute
when a human user is detected via a "enter the contents of this
graphic" procedure. Your <literal>ChannelProcessor</literal> would
respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration
attributes and redirect to an appropriate entry point to start the
human user validation process if the <literal>HttpSession</literal>
attribute is not currently set. </para>
<para>To decide whether a security check belongs in a
<literal>ChannelProcessor</literal> or an
<literal>AccessDecisionVoter</literal>, remember that the former is
designed to handle unauthenticated requests, whilst the latter is
designed to handle authenticated requests. The latter therefore has
access to the granted authorities of the authenticated principal. In
addition, problems detected by a <literal>ChannelProcessor</literal>
will generally cause a HTTP/HTTPS redirection so its requirements can
be met, whilst problems detected by an
<literal>AccessDecisionVoter</literal> will ultimately result in an
<literal>AccessDeniedException</literal> (depending on the governing
<literal>AccessDecisionManager</literal>).</para>
</sect2>
</sect1>

View File

@ -163,8 +163,6 @@
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
<property name="secureChannelEntryPoint"><ref bean="secureChannelEntryPoint"/></property>
<property name="insecureChannelEntryPoint"><ref bean="insecureChannelEntryPoint"/></property>
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
@ -175,17 +173,17 @@
</property>
</bean>
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/>
<bean id="secureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint">
<property name="portMapper"><ref bean="portMapper"/></property>
<property name="portResolver"><ref bean="portResolver"/></property>
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
<ref bean="insecureChannelProcessor"/>
</list>
</property>
</bean>
<bean id="insecureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint">
<property name="portMapper"><ref bean="portMapper"/></property>
<property name="portResolver"><ref bean="portResolver"/></property>
</bean>
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
@ -199,7 +197,6 @@
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
<property name="authenticationEntryPoint"><ref bean="casProcessingFilterEntryPoint"/></property>
<property name="portResolver"><ref bean="portResolver"/></property>
</bean>
<bean id="casProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
@ -207,14 +204,6 @@
<property name="serviceProperties"><ref bean="serviceProperties"/></property>
</bean>
<bean id="portMapper" class="net.sf.acegisecurity.util.PortMapperImpl"/>
<!-- Comment the always[Scheme]Port properties to use ServletRequest.getServerPort() -->
<bean id="portResolver" class="net.sf.acegisecurity.util.PortResolverImpl">
<property name="alwaysHttpPort"><value>8080</value></property>
<property name="alwaysHttpsPort"><value>8443</value></property>
</bean>
<bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">

View File

@ -140,8 +140,6 @@
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
<property name="secureChannelEntryPoint"><ref bean="secureChannelEntryPoint"/></property>
<property name="insecureChannelEntryPoint"><ref bean="insecureChannelEntryPoint"/></property>
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
@ -153,17 +151,17 @@
</property>
</bean>
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/>
<bean id="secureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint">
<property name="portMapper"><ref bean="portMapper"/></property>
<property name="portResolver"><ref bean="portResolver"/></property>
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
<ref bean="insecureChannelProcessor"/>
</list>
</property>
</bean>
<bean id="insecureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint">
<property name="portMapper"><ref bean="portMapper"/></property>
<property name="portResolver"><ref bean="portResolver"/></property>
</bean>
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
@ -177,22 +175,11 @@
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
<property name="authenticationEntryPoint"><ref bean="authenticationProcessingFilterEntryPoint"/></property>
<property name="portResolver"><ref bean="portResolver"/></property>
</bean>
<bean id="authenticationProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
<property name="forceHttps"><value>false</value></property>
<property name="portMapper"><ref bean="portMapper"/></property>
<property name="portResolver"><ref bean="portResolver"/></property>
</bean>
<bean id="portMapper" class="net.sf.acegisecurity.util.PortMapperImpl"/>
<!-- Comment the always[Scheme]Port properties to use ServletRequest.getServerPort() -->
<bean id="portResolver" class="net.sf.acegisecurity.util.PortResolverImpl">
<property name="alwaysHttpPort"><value>8080</value></property>
<property name="alwaysHttpsPort"><value>8443</value></property>
</bean>
<bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">

View File

@ -67,12 +67,12 @@
<!-- Remove the comments from the following <filter-mapping> if you'd
like to ensure secure URLs are only available over HTTPS -->
<!--
<filter-mapping>
<filter-name>Acegi Channel Processing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<filter-mapping>
<filter-name>Acegi Authentication Processing Filter</filter-name>