mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-27 06:12:27 +00:00
Filter to ensure web requests are received over a suitable secure channel.
This commit is contained in:
parent
73af01a477
commit
2c97583f27
@ -183,6 +183,7 @@
|
|||||||
<include name="net/sf/acegisecurity/vote/**"/>
|
<include name="net/sf/acegisecurity/vote/**"/>
|
||||||
<include name="net/sf/acegisecurity/ui/**"/>
|
<include name="net/sf/acegisecurity/ui/**"/>
|
||||||
<include name="net/sf/acegisecurity/util/**"/>
|
<include name="net/sf/acegisecurity/util/**"/>
|
||||||
|
<include name="net/sf/acegisecurity/securechannel/**"/>
|
||||||
<include name="net/sf/acegisecurity/intercept/**"/>
|
<include name="net/sf/acegisecurity/intercept/**"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/*"/>
|
<include name="net/sf/acegisecurity/adapters/*"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/catalina/*"/>
|
<include name="net/sf/acegisecurity/adapters/catalina/*"/>
|
||||||
@ -204,6 +205,7 @@
|
|||||||
<include name="net/sf/acegisecurity/vote/**"/>
|
<include name="net/sf/acegisecurity/vote/**"/>
|
||||||
<include name="net/sf/acegisecurity/ui/**"/>
|
<include name="net/sf/acegisecurity/ui/**"/>
|
||||||
<include name="net/sf/acegisecurity/util/**"/>
|
<include name="net/sf/acegisecurity/util/**"/>
|
||||||
|
<include name="net/sf/acegisecurity/securechannel/**"/>
|
||||||
<include name="net/sf/acegisecurity/intercept/**"/>
|
<include name="net/sf/acegisecurity/intercept/**"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/*"/>
|
<include name="net/sf/acegisecurity/adapters/*"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/jetty/*"/>
|
<include name="net/sf/acegisecurity/adapters/jetty/*"/>
|
||||||
@ -224,6 +226,7 @@
|
|||||||
<include name="net/sf/acegisecurity/vote/**"/>
|
<include name="net/sf/acegisecurity/vote/**"/>
|
||||||
<include name="net/sf/acegisecurity/ui/**"/>
|
<include name="net/sf/acegisecurity/ui/**"/>
|
||||||
<include name="net/sf/acegisecurity/util/**"/>
|
<include name="net/sf/acegisecurity/util/**"/>
|
||||||
|
<include name="net/sf/acegisecurity/securechannel/**"/>
|
||||||
<include name="net/sf/acegisecurity/intercept/**"/>
|
<include name="net/sf/acegisecurity/intercept/**"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/*"/>
|
<include name="net/sf/acegisecurity/adapters/*"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/jboss/*"/>
|
<include name="net/sf/acegisecurity/adapters/jboss/*"/>
|
||||||
@ -244,6 +247,7 @@
|
|||||||
<include name="net/sf/acegisecurity/vote/**"/>
|
<include name="net/sf/acegisecurity/vote/**"/>
|
||||||
<include name="net/sf/acegisecurity/ui/**"/>
|
<include name="net/sf/acegisecurity/ui/**"/>
|
||||||
<include name="net/sf/acegisecurity/util/**"/>
|
<include name="net/sf/acegisecurity/util/**"/>
|
||||||
|
<include name="net/sf/acegisecurity/securechannel/**"/>
|
||||||
<include name="net/sf/acegisecurity/intercept/**"/>
|
<include name="net/sf/acegisecurity/intercept/**"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/*"/>
|
<include name="net/sf/acegisecurity/adapters/*"/>
|
||||||
<include name="net/sf/acegisecurity/adapters/resin/*"/>
|
<include name="net/sf/acegisecurity/adapters/resin/*"/>
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/* 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.ConfigAttributeDefinition;
|
||||||
|
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decides whether a web channel provides sufficient security.
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public interface ChannelDecisionManager {
|
||||||
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decided whether the presented {@link FilterInvocation} provides
|
||||||
|
* sufficient security based on the requested {@link
|
||||||
|
* ConfigAttributeDefinition}.
|
||||||
|
*/
|
||||||
|
public void decide(FilterInvocation invocation,
|
||||||
|
ConfigAttributeDefinition config) throws SecureChannelRequiredException;
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/* 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.util.Iterator;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Requires a secure channel for a web request if a {@link
|
||||||
|
* ConfigAttribute#getAttribute()} keyword is detected.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* The default keyword string is <Code>REQUIRES_SECURE_CHANNEL</code>, but this
|
||||||
|
* may be overriden to any value. The <code>ConfigAttribute</code> must
|
||||||
|
* exactly match the case of the keyword string.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class ChannelDecisionManagerImpl implements InitializingBean,
|
||||||
|
ChannelDecisionManager {
|
||||||
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
private String keyword = "REQUIRES_SECURE_CHANNEL";
|
||||||
|
|
||||||
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
public void setKeyword(String keyword) {
|
||||||
|
this.keyword = keyword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeyword() {
|
||||||
|
return keyword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
if ((keyword == null) || "".equals(keyword)) {
|
||||||
|
throw new IllegalArgumentException("keyword required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void decide(FilterInvocation invocation,
|
||||||
|
ConfigAttributeDefinition config) throws SecureChannelRequiredException {
|
||||||
|
if ((invocation == null) || (config == null)) {
|
||||||
|
throw new IllegalArgumentException("Nulls cannot be provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator iter = config.getConfigAttributes();
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
ConfigAttribute attribute = (ConfigAttribute) iter.next();
|
||||||
|
|
||||||
|
if (attribute.equals(keyword)) {
|
||||||
|
if (!invocation.getHttpRequest().isSecure()) {
|
||||||
|
throw new SecureChannelRequiredException(
|
||||||
|
"Request is not being made over a secure channel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/* 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 java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by {@link ChannelProcessingFilter} to launch a secure web channel.
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public interface ChannelEntryPoint {
|
||||||
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commences a secure channel.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* Implementations should modify the headers on the
|
||||||
|
* <code>ServletResponse</code> as necessary to commence the user agent
|
||||||
|
* using the secure channel.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param request that resulted in a
|
||||||
|
* <code>SecureChannelRequiredException</code>
|
||||||
|
* @param response so that the user agent can begin using a secure channel
|
||||||
|
*/
|
||||||
|
public void commence(ServletRequest request, ServletResponse response)
|
||||||
|
throws IOException, ServletException;
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
/* 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.ConfigAttributeDefinition;
|
||||||
|
import net.sf.acegisecurity.intercept.web.FilterInvocation;
|
||||||
|
import net.sf.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures a request is delivered over a secure channel.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Internally uses a {@link FilterInvocation} to represent the request, so that
|
||||||
|
* the <code>FilterInvocation</code>-related property editors and lookup
|
||||||
|
* classes can be used.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* <B>Do not use this class directly.</B> Instead configure
|
||||||
|
* <code>web.xml</code> to use the {@link
|
||||||
|
* net.sf.acegisecurity.util.FilterToBeanProxy}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class ChannelProcessingFilter implements InitializingBean, Filter {
|
||||||
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(ChannelProcessingFilter.class);
|
||||||
|
|
||||||
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
private ChannelDecisionManager channelDecisionManager;
|
||||||
|
private ChannelEntryPoint channelEntryPoint;
|
||||||
|
private FilterInvocationDefinitionSource filterInvocationDefinitionSource;
|
||||||
|
|
||||||
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
public void setChannelDecisionManager(
|
||||||
|
ChannelDecisionManager channelDecisionManager) {
|
||||||
|
this.channelDecisionManager = channelDecisionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelDecisionManager getChannelDecisionManager() {
|
||||||
|
return channelDecisionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannelEntryPoint(ChannelEntryPoint channelEntryPoint) {
|
||||||
|
this.channelEntryPoint = channelEntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelEntryPoint getChannelEntryPoint() {
|
||||||
|
return channelEntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilterInvocationDefinitionSource(
|
||||||
|
FilterInvocationDefinitionSource filterInvocationDefinitionSource) {
|
||||||
|
this.filterInvocationDefinitionSource = filterInvocationDefinitionSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterInvocationDefinitionSource getFilterInvocationDefinitionSource() {
|
||||||
|
return filterInvocationDefinitionSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
if (filterInvocationDefinitionSource == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"filterInvocationDefinitionSource must be specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channelDecisionManager == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"channelDecisionManager must be specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channelEntryPoint == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"channelEntryPoint must be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {}
|
||||||
|
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response,
|
||||||
|
FilterChain chain) throws IOException, ServletException {
|
||||||
|
if (!(request instanceof HttpServletRequest)) {
|
||||||
|
throw new ServletException("HttpServletRequest required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(response instanceof HttpServletResponse)) {
|
||||||
|
throw new ServletException("HttpServletResponse required");
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterInvocation fi = new FilterInvocation(request, response, chain);
|
||||||
|
ConfigAttributeDefinition attr = this.filterInvocationDefinitionSource
|
||||||
|
.getAttributes(fi);
|
||||||
|
|
||||||
|
if (attr != null) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Request : " + request.toString()
|
||||||
|
+ "; ConfigAttributes: " + attr.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
channelDecisionManager.decide(fi, attr);
|
||||||
|
} catch (SecureChannelRequiredException channelException) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Channel insufficient ("
|
||||||
|
+ channelException.getMessage()
|
||||||
|
+ "); delegating to channelEntryPoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
channelEntryPoint.commence(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {}
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
/* 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 org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commences a secure channel by retrying the original request using HTTPS.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* This entry point should suffice in most circumstances. However, it is not
|
||||||
|
* intended to properly handle HTTP POSTs or other usage where a standard
|
||||||
|
* redirect would cause an issue.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class RetryWithHttpsEntryPoint implements InitializingBean,
|
||||||
|
ChannelEntryPoint {
|
||||||
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(RetryWithHttpsEntryPoint.class);
|
||||||
|
|
||||||
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
private Map httpsPortMappings;
|
||||||
|
|
||||||
|
//~ Constructors ===========================================================
|
||||||
|
|
||||||
|
public RetryWithHttpsEntryPoint() {
|
||||||
|
httpsPortMappings = new HashMap();
|
||||||
|
httpsPortMappings.put(new Integer(80), new Integer(443));
|
||||||
|
httpsPortMappings.put(new Integer(8080), new Integer(8443));
|
||||||
|
}
|
||||||
|
|
||||||
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Set to override the default http port to https port mappings of 80:443,
|
||||||
|
* and 8080:8443.
|
||||||
|
* </p>
|
||||||
|
* In a Spring XML ApplicationContext, a definition would look something
|
||||||
|
* like this:
|
||||||
|
* <pre>
|
||||||
|
* <property name="httpsPortMapping">
|
||||||
|
* <map>
|
||||||
|
* <entry key="80"><value>443</value></entry>
|
||||||
|
* <entry key="8080"><value>8443</value></entry>
|
||||||
|
* </map>
|
||||||
|
* </property>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param newMappings A Map consisting of String keys and String values,
|
||||||
|
* where for each entry the key is the string representation of an
|
||||||
|
* integer http port number, and the value is the string
|
||||||
|
* representation of the corresponding integer https port number.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if input map does not consist of String
|
||||||
|
* keys and values, each representing an integer port number in
|
||||||
|
* the range 1-65535 for that mapping.
|
||||||
|
*/
|
||||||
|
public void setHttpsPortMappings(HashMap newMappings) {
|
||||||
|
httpsPortMappings.clear();
|
||||||
|
|
||||||
|
Iterator it = newMappings.entrySet().iterator();
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Map.Entry entry = (Map.Entry) it.next();
|
||||||
|
Integer httpPort = new Integer((String) entry.getKey());
|
||||||
|
Integer httpsPort = new Integer((String) entry.getValue());
|
||||||
|
|
||||||
|
if ((httpPort.intValue() < 1) || (httpPort.intValue() > 65535)
|
||||||
|
|| (httpsPort.intValue() < 1) || (httpsPort.intValue() > 65535)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"one or both ports out of legal range: " + httpPort + ", "
|
||||||
|
+ httpsPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
httpsPortMappings.put(httpPort, httpsPort);
|
||||||
|
|
||||||
|
if (httpsPortMappings.size() < 1) {
|
||||||
|
throw new IllegalArgumentException("must map at least one port");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
if (httpsPortMappings == null) {
|
||||||
|
throw new IllegalArgumentException("httpsPortMappings required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commence(ServletRequest request, ServletResponse response)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
HttpServletRequest req = (HttpServletRequest) request;
|
||||||
|
|
||||||
|
String pathInfo = req.getPathInfo();
|
||||||
|
String queryString = req.getQueryString();
|
||||||
|
String contextPath = req.getContextPath();
|
||||||
|
String destination = req.getServletPath()
|
||||||
|
+ ((pathInfo == null) ? "" : pathInfo)
|
||||||
|
+ ((queryString == null) ? "" : ("?" + queryString));
|
||||||
|
|
||||||
|
String redirectUrl = contextPath;
|
||||||
|
|
||||||
|
Integer httpPort = new Integer(req.getServerPort());
|
||||||
|
Integer httpsPort = (Integer) httpsPortMappings.get(httpPort);
|
||||||
|
|
||||||
|
if (httpsPort != null) {
|
||||||
|
String serverName = req.getServerName();
|
||||||
|
redirectUrl = "https://" + serverName + ":" + httpsPort
|
||||||
|
+ contextPath + destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
((HttpServletResponse) response).sendRedirect(redirectUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the translated (Integer -> Integer) version of the original port
|
||||||
|
* mapping specified via setHttpsPortMapping()
|
||||||
|
*
|
||||||
|
* @return DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected Map getTranslatedHttpsPortMappings() {
|
||||||
|
return httpsPortMappings;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
Classes that ensure web requests are received over required
|
||||||
|
transport channels.
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -133,6 +133,25 @@
|
|||||||
|
|
||||||
<bean id="backendContactManagerTarget" class="sample.contact.ContactManagerBackend"/>
|
<bean id="backendContactManagerTarget" class="sample.contact.ContactManagerBackend"/>
|
||||||
|
|
||||||
|
<!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== -->
|
||||||
|
|
||||||
|
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
|
||||||
|
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
|
||||||
|
<property name="channelEntryPoint"><ref bean="channelEntryPoint"/></property>
|
||||||
|
<property name="filterInvocationDefinitionSource">
|
||||||
|
<value>
|
||||||
|
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
|
||||||
|
\A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
|
||||||
|
\A/info/.*\Z=REQUIRES_SECURE_CHANNEL
|
||||||
|
\A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/>
|
||||||
|
|
||||||
|
<bean id="channelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint"/>
|
||||||
|
|
||||||
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
|
<!-- ===================== HTTP REQUEST SECURITY ==================== -->
|
||||||
|
|
||||||
<bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
|
<bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
|
||||||
|
@ -24,6 +24,15 @@
|
|||||||
<param-value>/WEB-INF/applicationContext.xml</param-value>
|
<param-value>/WEB-INF/applicationContext.xml</param-value>
|
||||||
</context-param>
|
</context-param>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<filter-name>Acegi Channel Processing Filter</filter-name>
|
||||||
|
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>targetClass</param-name>
|
||||||
|
<param-value>net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
|
||||||
<filter>
|
<filter>
|
||||||
<filter-name>Acegi Authentication Processing Filter</filter-name>
|
<filter-name>Acegi Authentication Processing Filter</filter-name>
|
||||||
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
|
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
|
||||||
@ -56,6 +65,11 @@
|
|||||||
</init-param>
|
</init-param>
|
||||||
</filter>
|
</filter>
|
||||||
|
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>Acegi Channel Processing Filter</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
<filter-mapping>
|
<filter-mapping>
|
||||||
<filter-name>Acegi Authentication Processing Filter</filter-name>
|
<filter-name>Acegi Authentication Processing Filter</filter-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user