mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-25 11:43:29 +00:00
Make ChannelDecisionManagerImpl iterate through a list of channel security processors.
This commit is contained in:
parent
2421268baa
commit
ecac5a2eed
@ -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)
|
* 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 definable prefixes to avoid expectation of "ROLE_" GrantedAuthoritys
|
||||||
* Added pluggable AuthenticationEntryPoints to SecurityEnforcementFilter
|
* Added pluggable AuthenticationEntryPoints to SecurityEnforcementFilter
|
||||||
* Added Apache Ant path syntax support 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 JAR to Spring 1.0.1
|
||||||
* Updated several classes to use absolute (not relative) redirection URLs
|
* Updated several classes to use absolute (not relative) redirection URLs
|
||||||
* Refactored filters to use Spring application context lifecycle support
|
* Refactored filters to use Spring application context lifecycle support
|
||||||
|
@ -15,12 +15,23 @@
|
|||||||
|
|
||||||
package net.sf.acegisecurity.securechannel;
|
package net.sf.acegisecurity.securechannel;
|
||||||
|
|
||||||
|
import net.sf.acegisecurity.ConfigAttribute;
|
||||||
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
||||||
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decides whether a web channel provides sufficient security.
|
* 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
|
* @author Ben Alex
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
@ -34,6 +45,23 @@ public interface ChannelDecisionManager {
|
|||||||
* ConfigAttributeDefinition}.
|
* ConfigAttributeDefinition}.
|
||||||
*/
|
*/
|
||||||
public void decide(FilterInvocation invocation,
|
public void decide(FilterInvocation invocation,
|
||||||
ConfigAttributeDefinition config)
|
ConfigAttributeDefinition config) throws IOException, ServletException;
|
||||||
throws InsecureChannelRequiredException, SecureChannelRequiredException;
|
|
||||||
|
/**
|
||||||
|
* 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 org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Implementation of {@link ChannelDecisionManager}.
|
||||||
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Ensures configuration attribute requested channel security is present by
|
* Iterates through each configured {@link ChannelProcessor}. If a
|
||||||
* review of <code>HttpServletRequest.isSecure()</code> responses.
|
* <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>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* The class responds to two and only two case-sensitive keywords: {@link
|
* Once any response is committed (ie a redirect is written to the response
|
||||||
* #getInsecureKeyword()} and {@link #getSecureKeyword}. If either of these
|
* object), the <code>ChannelDecisionManagerImpl</code> will not iterate
|
||||||
* keywords are detected, <code>HttpServletRequest.isSecure()</code> is used
|
* through any further <code>ChannelProcessor</code>s.
|
||||||
* 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.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class ChannelDecisionManagerImpl implements InitializingBean,
|
public class ChannelDecisionManagerImpl implements ChannelDecisionManager,
|
||||||
ChannelDecisionManager {
|
InitializingBean {
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
private String insecureKeyword = "REQUIRES_INSECURE_CHANNEL";
|
private List channelProcessors;
|
||||||
private String secureKeyword = "REQUIRES_SECURE_CHANNEL";
|
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setInsecureKeyword(String insecureKeyword) {
|
public void setChannelProcessors(List newList) {
|
||||||
this.insecureKeyword = insecureKeyword;
|
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() {
|
public List getChannelProcessors() {
|
||||||
return insecureKeyword;
|
return this.channelProcessors;
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecureKeyword(String secureKeyword) {
|
|
||||||
this.secureKeyword = secureKeyword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSecureKeyword() {
|
|
||||||
return secureKeyword;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
if ((secureKeyword == null) || "".equals(secureKeyword)) {
|
checkIfValidList(this.channelProcessors);
|
||||||
throw new IllegalArgumentException("secureKeyword required");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((insecureKeyword == null) || "".equals(insecureKeyword)) {
|
|
||||||
throw new IllegalArgumentException("insecureKeyword required");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void decide(FilterInvocation invocation,
|
public void decide(FilterInvocation invocation,
|
||||||
ConfigAttributeDefinition config) throws SecureChannelRequiredException {
|
ConfigAttributeDefinition config) throws IOException, ServletException {
|
||||||
if ((invocation == null) || (config == null)) {
|
Iterator iter = this.channelProcessors.iterator();
|
||||||
throw new IllegalArgumentException("Nulls cannot be provided");
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator iter = config.getConfigAttributes();
|
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
ConfigAttribute attribute = (ConfigAttribute) iter.next();
|
ChannelProcessor processor = (ChannelProcessor) iter.next();
|
||||||
|
|
||||||
if (attribute.equals(secureKeyword)) {
|
processor.decide(invocation, config);
|
||||||
if (!invocation.getHttpRequest().isSecure()) {
|
|
||||||
throw new SecureChannelRequiredException(
|
|
||||||
"Request is not being made over a secure channel");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute.equals(insecureKeyword)) {
|
if (invocation.getResponse().isCommitted()) {
|
||||||
if (invocation.getHttpRequest().isSecure()) {
|
break;
|
||||||
throw new InsecureChannelRequiredException(
|
|
||||||
"Request is being made over a secure channel when an insecure channel is required");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>
|
* <P>
|
||||||
* Depending on the implementation, a secure or insecure channel will be
|
* <code>ChannelProcessor</code>s can elect to launch a new web channel
|
||||||
* launched.
|
* 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>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Ben Alex
|
* @author Ben Alex
|
||||||
@ -42,13 +44,10 @@ public interface ChannelEntryPoint {
|
|||||||
* <P>
|
* <P>
|
||||||
* Implementations should modify the headers on the
|
* Implementations should modify the headers on the
|
||||||
* <code>ServletResponse</code> as necessary to commence the user agent
|
* <code>ServletResponse</code> as necessary to commence the user agent
|
||||||
* using the implementation's supported channel type (ie secure or
|
* using the implementation's supported channel type.
|
||||||
* insecure).
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param request that resulted in a
|
* @param request that a <code>ChannelProcessor</code> has rejected
|
||||||
* <code>SecureChannelRequiredException</code> or
|
|
||||||
* <code>InsecureChannelRequiredException</code>
|
|
||||||
* @param response so that the user agent can begin using a new channel
|
* @param response so that the user agent can begin using a new channel
|
||||||
*/
|
*/
|
||||||
public void commence(ServletRequest request, ServletResponse response)
|
public void commence(ServletRequest request, ServletResponse response)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
package net.sf.acegisecurity.securechannel;
|
package net.sf.acegisecurity.securechannel;
|
||||||
|
|
||||||
|
import net.sf.acegisecurity.ConfigAttribute;
|
||||||
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
||||||
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
||||||
import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
|
import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
|
||||||
@ -26,6 +27,10 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.FilterConfig;
|
import javax.servlet.FilterConfig;
|
||||||
@ -46,6 +51,12 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <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
|
* <B>Do not use this class directly.</B> Instead configure
|
||||||
* <code>web.xml</code> to use the {@link
|
* <code>web.xml</code> to use the {@link
|
||||||
* net.sf.acegisecurity.util.FilterToBeanProxy}.
|
* net.sf.acegisecurity.util.FilterToBeanProxy}.
|
||||||
@ -62,8 +73,6 @@ public class ChannelProcessingFilter implements InitializingBean, Filter {
|
|||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
private ChannelDecisionManager channelDecisionManager;
|
private ChannelDecisionManager channelDecisionManager;
|
||||||
private ChannelEntryPoint insecureChannelEntryPoint;
|
|
||||||
private ChannelEntryPoint secureChannelEntryPoint;
|
|
||||||
private FilterInvocationDefinitionSource filterInvocationDefinitionSource;
|
private FilterInvocationDefinitionSource filterInvocationDefinitionSource;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
@ -86,23 +95,6 @@ public class ChannelProcessingFilter implements InitializingBean, Filter {
|
|||||||
return filterInvocationDefinitionSource;
|
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 {
|
public void afterPropertiesSet() throws Exception {
|
||||||
if (filterInvocationDefinitionSource == null) {
|
if (filterInvocationDefinitionSource == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
@ -114,14 +106,41 @@ public class ChannelProcessingFilter implements InitializingBean, Filter {
|
|||||||
"channelDecisionManager must be specified");
|
"channelDecisionManager must be specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secureChannelEntryPoint == null) {
|
Iterator iter = this.filterInvocationDefinitionSource
|
||||||
throw new IllegalArgumentException(
|
.getConfigAttributeDefinitions();
|
||||||
"secureChannelEntryPoint must be specified");
|
|
||||||
|
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(
|
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());
|
+ "; ConfigAttributes: " + attr.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
channelDecisionManager.decide(fi, attr);
|
||||||
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);
|
|
||||||
|
|
||||||
|
if (fi.getResponse().isCommitted()) {
|
||||||
return;
|
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() {
|
public boolean isCommitted() {
|
||||||
throw new UnsupportedOperationException("mock method not implemented");
|
if (redirect == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentLength(int arg0) {
|
public void setContentLength(int arg0) {
|
||||||
|
@ -17,6 +17,7 @@ package net.sf.acegisecurity.securechannel;
|
|||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import net.sf.acegisecurity.ConfigAttribute;
|
||||||
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
||||||
import net.sf.acegisecurity.MockFilterChain;
|
import net.sf.acegisecurity.MockFilterChain;
|
||||||
import net.sf.acegisecurity.MockHttpServletRequest;
|
import net.sf.acegisecurity.MockHttpServletRequest;
|
||||||
@ -24,6 +25,14 @@ import net.sf.acegisecurity.MockHttpServletResponse;
|
|||||||
import net.sf.acegisecurity.SecurityConfig;
|
import net.sf.acegisecurity.SecurityConfig;
|
||||||
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
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}.
|
* Tests {@link ChannelDecisionManagerImpl}.
|
||||||
@ -42,141 +51,175 @@ public class ChannelDecisionManagerImplTests extends TestCase {
|
|||||||
junit.textui.TestRunner.run(ChannelDecisionManagerImplTests.class);
|
junit.textui.TestRunner.run(ChannelDecisionManagerImplTests.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDetectsInvalidInsecureKeyword() throws Exception {
|
public void testCannotSetEmptyChannelProcessorsList()
|
||||||
|
throws Exception {
|
||||||
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
||||||
cdm.setInsecureKeyword("");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cdm.afterPropertiesSet();
|
cdm.setChannelProcessors(new Vector());
|
||||||
fail("Should have thrown IllegalArgumentException");
|
fail("Should have thrown IllegalArgumentException");
|
||||||
} catch (IllegalArgumentException expected) {
|
} catch (IllegalArgumentException expected) {
|
||||||
assertEquals("insecureKeyword required", expected.getMessage());
|
assertEquals("A list of ChannelProcessors is required",
|
||||||
}
|
expected.getMessage());
|
||||||
|
|
||||||
cdm.setInsecureKeyword(null);
|
|
||||||
|
|
||||||
try {
|
|
||||||
cdm.afterPropertiesSet();
|
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
|
||||||
assertEquals("insecureKeyword required", expected.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDetectsInvalidSecureKeyword() throws Exception {
|
public void testCannotSetIncorrectObjectTypesIntoChannelProcessorsList()
|
||||||
|
throws Exception {
|
||||||
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
||||||
cdm.setSecureKeyword("");
|
List list = new Vector();
|
||||||
|
list.add("THIS IS NOT A CHANNELPROCESSOR");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cdm.afterPropertiesSet();
|
cdm.setChannelProcessors(list);
|
||||||
fail("Should have thrown IllegalArgumentException");
|
fail("Should have thrown IllegalArgumentException");
|
||||||
} catch (IllegalArgumentException expected) {
|
} 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);
|
assertTrue(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDetectsWhenSecureChannelNeeded() {
|
public void testCannotSetNullChannelProcessorsList()
|
||||||
ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
|
throws Exception {
|
||||||
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");
|
|
||||||
|
|
||||||
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cdm.decide(new FilterInvocation(request,
|
cdm.setChannelProcessors(null);
|
||||||
new MockHttpServletResponse(), new MockFilterChain()), attr);
|
fail("Should have thrown IllegalArgumentException");
|
||||||
} catch (SecureChannelRequiredException expected) {
|
} catch (IllegalArgumentException expected) {
|
||||||
assertTrue(true);
|
assertEquals("A list of ChannelProcessors is required",
|
||||||
|
expected.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetterSetters() throws Exception {
|
public void testDecideIsOperational() throws Exception {
|
||||||
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
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();
|
cdm.afterPropertiesSet();
|
||||||
assertEquals("REQUIRES_INSECURE_CHANNEL", cdm.getInsecureKeyword());
|
|
||||||
assertEquals("REQUIRES_SECURE_CHANNEL", cdm.getSecureKeyword());
|
|
||||||
|
|
||||||
cdm.setInsecureKeyword("MY_INSECURE");
|
MockHttpServletRequest request = new MockHttpServletRequest("not used");
|
||||||
cdm.setSecureKeyword("MY_SECURE");
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
MockFilterChain chain = new MockFilterChain();
|
||||||
|
FilterInvocation fi = new FilterInvocation(request, response, chain);
|
||||||
|
|
||||||
assertEquals("MY_INSECURE", cdm.getInsecureKeyword());
|
ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
|
||||||
assertEquals("MY_SECURE", cdm.getSecureKeyword());
|
cad.addConfigAttribute(new SecurityConfig("xyz"));
|
||||||
|
|
||||||
|
cdm.decide(fi, cad);
|
||||||
|
assertTrue(fi.getResponse().isCommitted());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIgnoresOtherConfigAttributes() {
|
public void testDecideIteratesAllProcessorsIfNoneCommitAResponse()
|
||||||
ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
|
throws Exception {
|
||||||
attr.addConfigAttribute(new SecurityConfig("XYZ"));
|
|
||||||
|
|
||||||
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
|
||||||
cdm.decide(new FilterInvocation(new MockHttpServletRequest("x"),
|
MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
|
||||||
new MockHttpServletResponse(), new MockFilterChain()), attr);
|
MockChannelProcessor cpAbc = new MockChannelProcessor("abc", false);
|
||||||
assertTrue(true);
|
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 junit.framework.TestCase;
|
||||||
|
|
||||||
|
import net.sf.acegisecurity.ConfigAttribute;
|
||||||
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
||||||
import net.sf.acegisecurity.MockFilterConfig;
|
|
||||||
import net.sf.acegisecurity.MockHttpServletRequest;
|
import net.sf.acegisecurity.MockHttpServletRequest;
|
||||||
import net.sf.acegisecurity.MockHttpServletResponse;
|
import net.sf.acegisecurity.MockHttpServletResponse;
|
||||||
import net.sf.acegisecurity.SecurityConfig;
|
import net.sf.acegisecurity.SecurityConfig;
|
||||||
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
||||||
import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
|
import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
|
||||||
import net.sf.acegisecurity.intercept.web.RegExpBasedFilterInvocationDefinitionMap;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
@ -53,61 +54,16 @@ public class ChannelProcessingFilterTests extends TestCase {
|
|||||||
junit.textui.TestRunner.run(ChannelProcessingFilterTests.class);
|
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()
|
public void testDetectsMissingChannelDecisionManager()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
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 {
|
try {
|
||||||
filter.afterPropertiesSet();
|
filter.afterPropertiesSet();
|
||||||
@ -118,12 +74,11 @@ public class ChannelProcessingFilterTests extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDetectsMissingFilterInvocationDefinitionMap()
|
public void testDetectsMissingFilterInvocationDefinitionSource()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
||||||
filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
|
filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
|
||||||
filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
|
"MOCK"));
|
||||||
filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
filter.afterPropertiesSet();
|
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 {
|
throws Exception {
|
||||||
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
||||||
filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
|
filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
|
||||||
filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
|
"SUPPORTS_MOCK_ONLY"));
|
||||||
filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
|
|
||||||
|
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 {
|
try {
|
||||||
filter.afterPropertiesSet();
|
filter.afterPropertiesSet();
|
||||||
fail("Should have thrown IllegalArgumentException");
|
fail("Should have thrown IllegalArgumentException");
|
||||||
} catch (IllegalArgumentException expected) {
|
} catch (IllegalArgumentException expected) {
|
||||||
assertEquals("insecureChannelEntryPoint must be specified",
|
assertTrue(expected.getMessage().startsWith("Unsupported configuration attributes:"));
|
||||||
expected.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDetectsMissingSecureChannelEntryPoint()
|
public void testDoFilterWhenManagerDoesCommitResponse()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
||||||
filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
|
filter.setChannelDecisionManager(new MockChannelDecisionManager(true,
|
||||||
filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
|
"SOME_ATTRIBUTE"));
|
||||||
filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
|
|
||||||
|
|
||||||
try {
|
ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
|
||||||
filter.afterPropertiesSet();
|
attr.addConfigAttribute(new SecurityConfig("SOME_ATTRIBUTE"));
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
|
||||||
assertEquals("secureChannelEntryPoint must be specified",
|
attr, true);
|
||||||
expected.getMessage());
|
|
||||||
}
|
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()
|
public void testDoFilterWithNonHttpServletRequestDetected()
|
||||||
@ -192,91 +227,55 @@ public class ChannelProcessingFilterTests extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDoesNotInterruptRequestsWithCorrectChannelSecurity()
|
public void testGetterSetters() throws Exception {
|
||||||
throws Exception {
|
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
||||||
|
filter.setChannelDecisionManager(new MockChannelDecisionManager(false,
|
||||||
|
"MOCK"));
|
||||||
|
assertTrue(filter.getChannelDecisionManager() != null);
|
||||||
|
|
||||||
ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
|
ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
|
||||||
attr.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
|
attr.addConfigAttribute(new SecurityConfig("MOCK"));
|
||||||
|
|
||||||
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
|
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path",
|
||||||
attr);
|
attr, false);
|
||||||
|
|
||||||
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
|
||||||
filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
|
|
||||||
filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
|
|
||||||
filter.setFilterInvocationDefinitionSource(fids);
|
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.getFilterInvocationDefinitionSource() != null);
|
||||||
assertTrue(filter.getChannelDecisionManager() != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testLifecycle() throws Exception {
|
filter.init(null);
|
||||||
ChannelProcessingFilter filter = new ChannelProcessingFilter();
|
|
||||||
filter.setInsecureChannelEntryPoint(new RetryWithHttpEntryPoint());
|
|
||||||
filter.setSecureChannelEntryPoint(new RetryWithHttpsEntryPoint());
|
|
||||||
filter.setFilterInvocationDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
|
|
||||||
filter.setChannelDecisionManager(new ChannelDecisionManagerImpl());
|
|
||||||
filter.afterPropertiesSet();
|
filter.afterPropertiesSet();
|
||||||
|
|
||||||
filter.init(new MockFilterConfig());
|
|
||||||
filter.destroy();
|
filter.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ Inner Classes ==========================================================
|
//~ Inner Classes ==========================================================
|
||||||
|
|
||||||
private class MockEntryPoint implements ChannelEntryPoint {
|
private class MockChannelDecisionManager implements ChannelDecisionManager {
|
||||||
private boolean expectToBeCalled;
|
private String supportAttribute;
|
||||||
|
private boolean commitAResponse;
|
||||||
|
|
||||||
public MockEntryPoint(boolean expectToBeCalled) {
|
public MockChannelDecisionManager(boolean commitAResponse,
|
||||||
this.expectToBeCalled = expectToBeCalled;
|
String supportAttribute) {
|
||||||
|
this.commitAResponse = commitAResponse;
|
||||||
|
this.supportAttribute = supportAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MockEntryPoint() {
|
private MockChannelDecisionManager() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void commence(ServletRequest request, ServletResponse response)
|
public void decide(FilterInvocation invocation,
|
||||||
|
ConfigAttributeDefinition config)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
if (expectToBeCalled) {
|
if (commitAResponse) {
|
||||||
assertTrue(true);
|
invocation.getHttpResponse().sendRedirect("/redirected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supports(ConfigAttribute attribute) {
|
||||||
|
if (attribute.getAttribute().equals(supportAttribute)) {
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
fail("Did not expect this ChannelEntryPoint to be called");
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,11 +305,13 @@ public class ChannelProcessingFilterTests extends TestCase {
|
|||||||
implements FilterInvocationDefinitionSource {
|
implements FilterInvocationDefinitionSource {
|
||||||
private ConfigAttributeDefinition toReturn;
|
private ConfigAttributeDefinition toReturn;
|
||||||
private String servletPath;
|
private String servletPath;
|
||||||
|
private boolean provideIterator;
|
||||||
|
|
||||||
public MockFilterInvocationDefinitionMap(String servletPath,
|
public MockFilterInvocationDefinitionMap(String servletPath,
|
||||||
ConfigAttributeDefinition toReturn) {
|
ConfigAttributeDefinition toReturn, boolean provideIterator) {
|
||||||
this.servletPath = servletPath;
|
this.servletPath = servletPath;
|
||||||
this.toReturn = toReturn;
|
this.toReturn = toReturn;
|
||||||
|
this.provideIterator = provideIterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MockFilterInvocationDefinitionMap() {
|
private MockFilterInvocationDefinitionMap() {
|
||||||
@ -329,7 +330,14 @@ public class ChannelProcessingFilterTests extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Iterator getConfigAttributeDefinitions() {
|
public Iterator getConfigAttributeDefinitions() {
|
||||||
return null;
|
if (!provideIterator) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List list = new Vector();
|
||||||
|
list.add(toReturn);
|
||||||
|
|
||||||
|
return list.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supports(Class clazz) {
|
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")));
|
||||||
|
}
|
||||||
|
}
|
@ -522,20 +522,17 @@
|
|||||||
Acegi Security System for Spring use this class. Refer to the Filters
|
Acegi Security System for Spring use this class. Refer to the Filters
|
||||||
section to learn more about this bean.</para>
|
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>
|
beans:</para>
|
||||||
|
|
||||||
<programlisting><bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
|
<programlisting><bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
|
||||||
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
|
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
|
||||||
<property name="authenticationEntryPoint"><ref bean="authenticationEntryPoint"/></property>
|
<property name="authenticationEntryPoint"><ref bean="authenticationEntryPoint"/></property>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
|
<bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
|
||||||
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
|
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
|
||||||
<property name="forceHttps"><value>false</value></property>
|
<property name="forceHttps"><value>false</value></property>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
|
||||||
<property name="portMapper"><ref bean="portMapper"/></property>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
|
<bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
|
||||||
@ -549,12 +546,6 @@
|
|||||||
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
|
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- 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></programlisting>
|
</bean></programlisting>
|
||||||
|
|
||||||
<para>The <literal>AuthenticationEntryPoint</literal> will be called
|
<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
|
properties related to forcing the use of HTTPS, so please refer to the
|
||||||
JavaDocs if you require this.</para>
|
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
|
<para>The <literal>PortMapper</literal> provides information on which
|
||||||
HTTPS ports correspond to which HTTP ports. This is used by the
|
HTTPS ports correspond to which HTTP ports. This is used by the
|
||||||
<literal>AuthenticationProcessingFilterEntryPoint</literal> and
|
<literal>AuthenticationProcessingFilterEntryPoint</literal> and
|
||||||
@ -2756,10 +2740,12 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
|
|||||||
|
|
||||||
<para>In addition to coordinating the authentication and authorization
|
<para>In addition to coordinating the authentication and authorization
|
||||||
requirements of your application, the Acegi Security System for Spring
|
requirements of your application, the Acegi Security System for Spring
|
||||||
is also able to ensure web requests are received using an appropriate
|
is also able to ensure unauthenticated web requests have certain
|
||||||
transport. If your application has many security requirements, you'll
|
properties. These properties may include being of a particular
|
||||||
probably want to use HTTPS as the transport, whilst less secure pages
|
transport type, having a particular <literal>HttpSession</literal>
|
||||||
can use the unencrypted HTTP transport.</para>
|
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
|
<para>An important issue in considering transport security is that of
|
||||||
session hijacking. Your web container manages a
|
session hijacking. Your web container manages a
|
||||||
@ -2809,30 +2795,28 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
|
|||||||
|
|
||||||
<para><programlisting><bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
|
<para><programlisting><bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
|
||||||
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
|
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
|
||||||
<property name="secureChannelEntryPoint"><ref bean="secureChannelEntryPoint"/></property>
|
|
||||||
<property name="insecureChannelEntryPoint"><ref bean="insecureChannelEntryPoint"/></property>
|
|
||||||
<property name="filterInvocationDefinitionSource">
|
<property name="filterInvocationDefinitionSource">
|
||||||
<value>
|
<value>
|
||||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||||
\A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
|
\A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
|
||||||
\A/acegilogin.jsp.*\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
|
\A.*\Z=REQUIRES_INSECURE_CHANNEL
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/>
|
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
|
||||||
|
<property name="channelProcessors">
|
||||||
<bean id="secureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint">
|
<list>
|
||||||
<property name="portMapper"><ref bean="portMapper"/></property>
|
<ref bean="secureChannelProcessor"/>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
<ref bean="insecureChannelProcessor"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="insecureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint">
|
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
|
||||||
<property name="portMapper"><ref bean="portMapper"/></property>
|
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/></programlisting></para>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
|
||||||
</bean></programlisting></para>
|
|
||||||
|
|
||||||
<para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
|
<para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
|
||||||
style paths are also supported by the
|
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
|
attributes that apply. It then delegates to the
|
||||||
<literal>ChannelDecisionManager</literal>. The default implementation,
|
<literal>ChannelDecisionManager</literal>. The default implementation,
|
||||||
<literal>ChannelDecisionManagerImpl</literal>, should suffice in most
|
<literal>ChannelDecisionManagerImpl</literal>, should suffice in most
|
||||||
cases. It simply throws a
|
cases. It simply delegates through the list of configured
|
||||||
<literal>SecureChannelRequiredException</literal> or
|
<literal>ChannelProcessor</literal> instances. A
|
||||||
<literal>InsecureChannelRequiredException</literal> if the request's
|
<literal>ChannelProcessor</literal> will review the request, and if it
|
||||||
transport channel carries too little or too much security
|
is unhappy with the request (eg it was received across the incorrect
|
||||||
respectively. </para>
|
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
|
<para>Included with the Acegi Security System for Spring are two
|
||||||
<literal>SecureChannelRequiredException</literal> or
|
concrete <literal>ChannelProcessor</literal> implementations:
|
||||||
<literal>InsecureChannelRequiredException</literal> and delegate to
|
<literal>SecureChannelProcessor</literal> ensures requests with a
|
||||||
the <literal>secureChannelEntryPoint</literal> or
|
configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
|
||||||
<literal>insecureChannelEntryPoint</literal> respectively. These entry
|
are received over HTTPS, whilst
|
||||||
points implement the <literal>ChannelEntryPoint</literal> interface,
|
<literal>InsecureChannelProcessor</literal> ensures requests with a
|
||||||
which allows the implementation to perform a redirect or take similar
|
configuration attribute of
|
||||||
action. The included <literal>RetryWithHttpsEntryPoint</literal> and
|
<literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
|
||||||
<literal>RetryWithHttpEntryPoint</literal> implementations simply
|
Both implementations delegate to a
|
||||||
perform a redirect.</para>
|
<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
|
<para>Note that the redirections are absolute (eg
|
||||||
http://www.company.com:8080/app/page), not relative (eg /app/page).
|
http://www.company.com:8080/app/page), not relative (eg /app/page).
|
||||||
During testing it was discovered that Internet Explorer 6 Service Pack
|
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
|
1 has a bug whereby it does not respond correctly to a redirection
|
||||||
redirection instruction which also changes the port to use.
|
instruction which also changes the port to use. Accordingly, absolute
|
||||||
Accordingly, absolute URLs are used in conjunction with the
|
URLs are used in conjunction with bug detection logic in the
|
||||||
<literal>PortResolver</literal> interface to overcome this issue. The
|
<literal>PortResolverImpl</literal> that is wired up by default to
|
||||||
<literal>PortResolverImpl</literal> is the included implementation,
|
many Acegi Security beans. Please refer to the JavaDocs for
|
||||||
and is capable of determining the port a request was received on
|
<literal>PortResolverImpl</literal> for further details.</para>
|
||||||
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>
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="security-channels-usage">
|
<sect2 id="security-channels-usage">
|
||||||
@ -2885,6 +2874,29 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
|
|||||||
<literal>web.xml</literal> <literal><welcome-file></literal> or
|
<literal>web.xml</literal> <literal><welcome-file></literal> or
|
||||||
a well-known home page URL), but once this is done the filter will
|
a well-known home page URL), but once this is done the filter will
|
||||||
perform redirects as defined by your application context.</para>
|
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>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
@ -163,8 +163,6 @@
|
|||||||
|
|
||||||
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
|
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
|
||||||
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
|
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
|
||||||
<property name="secureChannelEntryPoint"><ref bean="secureChannelEntryPoint"/></property>
|
|
||||||
<property name="insecureChannelEntryPoint"><ref bean="insecureChannelEntryPoint"/></property>
|
|
||||||
<property name="filterInvocationDefinitionSource">
|
<property name="filterInvocationDefinitionSource">
|
||||||
<value>
|
<value>
|
||||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||||
@ -175,17 +173,17 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/>
|
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
|
||||||
|
<property name="channelProcessors">
|
||||||
<bean id="secureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint">
|
<list>
|
||||||
<property name="portMapper"><ref bean="portMapper"/></property>
|
<ref bean="secureChannelProcessor"/>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
<ref bean="insecureChannelProcessor"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="insecureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint">
|
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
|
||||||
<property name="portMapper"><ref bean="portMapper"/></property>
|
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
|
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
|
||||||
|
|
||||||
@ -199,7 +197,6 @@
|
|||||||
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
|
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
|
||||||
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
|
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
|
||||||
<property name="authenticationEntryPoint"><ref bean="casProcessingFilterEntryPoint"/></property>
|
<property name="authenticationEntryPoint"><ref bean="casProcessingFilterEntryPoint"/></property>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="casProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
|
<bean id="casProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
|
||||||
@ -207,14 +204,6 @@
|
|||||||
<property name="serviceProperties"><ref bean="serviceProperties"/></property>
|
<property name="serviceProperties"><ref bean="serviceProperties"/></property>
|
||||||
</bean>
|
</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">
|
<bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
|
||||||
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
|
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
|
||||||
<property name="decisionVoters">
|
<property name="decisionVoters">
|
||||||
|
@ -140,8 +140,6 @@
|
|||||||
|
|
||||||
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
|
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
|
||||||
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
|
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
|
||||||
<property name="secureChannelEntryPoint"><ref bean="secureChannelEntryPoint"/></property>
|
|
||||||
<property name="insecureChannelEntryPoint"><ref bean="insecureChannelEntryPoint"/></property>
|
|
||||||
<property name="filterInvocationDefinitionSource">
|
<property name="filterInvocationDefinitionSource">
|
||||||
<value>
|
<value>
|
||||||
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||||
@ -153,17 +151,17 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/>
|
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
|
||||||
|
<property name="channelProcessors">
|
||||||
<bean id="secureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint">
|
<list>
|
||||||
<property name="portMapper"><ref bean="portMapper"/></property>
|
<ref bean="secureChannelProcessor"/>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
<ref bean="insecureChannelProcessor"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="insecureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint">
|
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
|
||||||
<property name="portMapper"><ref bean="portMapper"/></property>
|
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
|
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
|
||||||
|
|
||||||
@ -177,22 +175,11 @@
|
|||||||
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
|
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
|
||||||
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
|
<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
|
||||||
<property name="authenticationEntryPoint"><ref bean="authenticationProcessingFilterEntryPoint"/></property>
|
<property name="authenticationEntryPoint"><ref bean="authenticationProcessingFilterEntryPoint"/></property>
|
||||||
<property name="portResolver"><ref bean="portResolver"/></property>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="authenticationProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
|
<bean id="authenticationProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
|
||||||
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
|
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
|
||||||
<property name="forceHttps"><value>false</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>
|
||||||
|
|
||||||
<bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
|
<bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
|
||||||
|
@ -67,12 +67,12 @@
|
|||||||
|
|
||||||
<!-- Remove the comments from the following <filter-mapping> if you'd
|
<!-- Remove the comments from the following <filter-mapping> if you'd
|
||||||
like to ensure secure URLs are only available over HTTPS -->
|
like to ensure secure URLs are only available over HTTPS -->
|
||||||
<!--
|
|
||||||
<filter-mapping>
|
<filter-mapping>
|
||||||
<filter-name>Acegi Channel Processing Filter</filter-name>
|
<filter-name>Acegi Channel Processing Filter</filter-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</filter-mapping>
|
</filter-mapping>
|
||||||
-->
|
|
||||||
|
|
||||||
<filter-mapping>
|
<filter-mapping>
|
||||||
<filter-name>Acegi Authentication Processing Filter</filter-name>
|
<filter-name>Acegi Authentication Processing Filter</filter-name>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user