You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by lh...@apache.org on 2009/03/30 18:56:57 UTC
svn commit: r760043 - in /incubator/jsecurity/trunk:
core/src/main/java/org/apache/ki/util/
web/src/main/java/org/apache/ki/web/config/
web/src/main/java/org/apache/ki/web/filter/
web/src/main/java/org/apache/ki/web/filter/authz/
Author: lhazlewood
Date: Mon Mar 30 16:56:57 2009
New Revision: 760043
URL: http://svn.apache.org/viewvc?rev=760043&view=rev
Log:
Added two new default filters - 'port' and 'ssl' to ensure a request comes in on a certain port (with the 'ssl' filter being a PortFilter that just defaults to 443).
Added:
incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/PortFilter.java
incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/SslFilter.java
Modified:
incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/util/StringUtils.java
incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/config/IniWebConfiguration.java
incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/AccessControlFilter.java
Modified: incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/util/StringUtils.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/util/StringUtils.java?rev=760043&r1=760042&r2=760043&view=diff
==============================================================================
--- incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/util/StringUtils.java (original)
+++ incubator/jsecurity/trunk/core/src/main/java/org/apache/ki/util/StringUtils.java Mon Mar 30 16:56:57 2009
@@ -157,6 +157,39 @@
}
/**
+ * Returns the specified array as a comma-delimited (',') string.
+ * @param array the array whose contents will be converted to a string.
+ * @return the array's contents as a comma-delimited (',') string.
+ * @since 1.0
+ */
+ public static String toString(Object[] array) {
+ return toDelimitedString(array,",");
+ }
+
+ /**
+ * Returns the array's contents as a string, with each element delimited by the specified
+ * {@code delimiter} argument. Useful for {@code toString()} implementations and log messages.
+ *
+ * @param array the array whose contents will be converted to a string
+ * @param delimiter the delimiter to use between each element
+ * @return a single string, delimited by the specified {@code delimiter}.
+ * @since 1.0
+ */
+ public static String toDelimitedString(Object[] array, String delimiter ) {
+ if ( array == null || array.length == 0 ) {
+ return EMPTY_STRING;
+ }
+ StringBuffer sb = new StringBuffer();
+ for( int i=0; i < array.length; i++ ) {
+ if ( i > 0 ) {
+ sb.append(delimiter);
+ }
+ sb.append(array[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
* Tokenize the given String into a String array via a StringTokenizer.
* Trims tokens and omits empty tokens.
* <p>The given delimiters string is supposed to consist of any number of
Modified: incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/config/IniWebConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/config/IniWebConfiguration.java?rev=760043&r1=760042&r2=760043&view=diff
==============================================================================
--- incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/config/IniWebConfiguration.java (original)
+++ incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/config/IniWebConfiguration.java Mon Mar 30 16:56:57 2009
@@ -50,6 +50,8 @@
import org.apache.ki.web.filter.authc.UserFilter;
import org.apache.ki.web.filter.authz.PermissionsAuthorizationFilter;
import org.apache.ki.web.filter.authz.RolesAuthorizationFilter;
+import org.apache.ki.web.filter.authz.PortFilter;
+import org.apache.ki.web.filter.authz.SslFilter;
import org.apache.ki.web.servlet.AdviceFilter;
import org.apache.ki.web.servlet.ProxiedFilterChain;
@@ -138,7 +140,7 @@
if (pathMatches(path, requestURI)) {
if (log.isTraceEnabled()) {
log.trace("Matched path [" + path + "] for requestURI [" + requestURI + "]. " +
- "Utilizing corresponding filter chain...");
+ "Utilizing corresponding filter chain...");
}
return getChain(path, originalChain);
}
@@ -315,8 +317,8 @@
protected void assertFilter(String name, Object o) throws ConfigurationException {
if (!(o instanceof Filter)) {
String msg = "[" + FILTERS + "] section specified a filter named '" + name + "', which does not " +
- "implement the " + Filter.class.getName() + " interface. Only Filter implementations may be " +
- "defined.";
+ "implement the " + Filter.class.getName() + " interface. Only Filter implementations may be " +
+ "defined.";
throw new ConfigurationException(msg);
}
}
@@ -354,6 +356,16 @@
filter.setName(name);
filters.put(name, filter);
+ name = "port";
+ filter = new PortFilter();
+ filter.setName(name);
+ filters.put(name, filter);
+
+ name = "ssl";
+ filter = new SslFilter();
+ filter.setName(name);
+ filters.put(name, filter);
+
return filters;
}
@@ -416,13 +428,13 @@
Filter filter = filters.get(name);
if (filter == null) {
String msg = "Path [" + path + "] specified a filter named '" + name + "', but that " +
- "filter has not been specified in the [" + FILTERS + "] section.";
+ "filter has not been specified in the [" + FILTERS + "] section.";
throw new ConfigurationException(msg);
}
if (filter instanceof PathConfigProcessor) {
if (log.isDebugEnabled()) {
log.debug("Applying path [" + path + "] to filter [" + name + "] " +
- "with config [" + config + "]");
+ "with config [" + config + "]");
}
((PathConfigProcessor) filter).processPathConfig(path, config);
}
Modified: incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/AccessControlFilter.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/AccessControlFilter.java?rev=760043&r1=760042&r2=760043&view=diff
==============================================================================
--- incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/AccessControlFilter.java (original)
+++ incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/AccessControlFilter.java Mon Mar 30 16:56:57 2009
@@ -102,7 +102,7 @@
/**
* Returns <code>true</code> if the request is allowed to proceed through the filter normally, or <code>false</code>
* if the request should be handled by the
- * {@link #onAccessDenied(javax.servlet.ServletRequest, javax.servlet.ServletResponse) onAccessDenied(request,response)}
+ * {@link #onAccessDenied(ServletRequest,ServletResponse,Object) onAccessDenied(request,response,mappedValue)}
* method instead.
*
* @param request the incoming <code>ServletRequest</code>
@@ -110,7 +110,7 @@
* @param mappedValue the filter-specific config value mapped to this filter in the URL rules mappings.
* @return <code>true</code> if the request should proceed through the filter normally, <code>false</code> if the
* request should be processed by this filter's
- * {@link #onAccessDenied(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} method instead.
+ * {@link #onAccessDenied(ServletRequest,ServletResponse,Object)} method instead.
* @throws Exception if an error occurs during processing.
*/
protected abstract boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception;
@@ -118,6 +118,26 @@
/**
* Processes requests where the subject was denied access as determined by the
* {@link #isAccessAllowed(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Object) isAccessAllowed}
+ * method, retaining the {@code mappedValue} that was used during configuration.
+ * <p/>
+ * This method immediately delegates to {@link #onAccessDenied(ServletRequest,ServletResponse)} as a
+ * convenience in that most post-denial behavior does not need the mapped config again.
+ *
+ * @param request the incoming <code>ServletRequest</code>
+ * @param response the outgoing <code>ServletResponse</code>
+ * @param mappedValue the config specified for the filter in the matching request's filter chain.
+ * @return <code>true</code> if the request should continue to be processed; false if the subclass will
+ * handle/render the response directly.
+ * @throws Exception if there is an error processing the request.
+ * @since 1.0
+ */
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
+ return onAccessDenied(request, response);
+ }
+
+ /**
+ * Processes requests where the subject was denied access as determined by the
+ * {@link #isAccessAllowed(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Object) isAccessAllowed}
* method.
*
* @param request the incoming <code>ServletRequest</code>
@@ -130,9 +150,9 @@
/**
* Returns <code>true</code> if
- * {@link #isAccessAllowed(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Object) isAccessAllowed},
+ * {@link #isAccessAllowed(ServletRequest,ServletResponse,Object) isAccessAllowed(Request,Response,Object)},
* otherwise returns the result of
- * {@link #onAccessDenied(javax.servlet.ServletRequest, javax.servlet.ServletResponse) onAccessDenied}.
+ * {@link #onAccessDenied(ServletRequest,ServletResponse,Object) onAccessDenied(Request,Response,Object)}.
*
* @return <code>true</code> if
* {@link #isAccessAllowed(javax.servlet.ServletRequest, javax.servlet.ServletResponse, Object) isAccessAllowed},
@@ -142,7 +162,7 @@
*/
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
//mapped value is ignored - not needed for most (if not all) authc Filters.
- return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response);
+ return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
}
/**
Added: incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/PortFilter.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/PortFilter.java?rev=760043&view=auto
==============================================================================
--- incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/PortFilter.java (added)
+++ incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/PortFilter.java Mon Mar 30 16:56:57 2009
@@ -0,0 +1,78 @@
+package org.apache.ki.web.filter.authz;
+
+import org.apache.ki.config.ConfigurationException;
+import org.apache.ki.util.StringUtils;
+import org.apache.ki.web.WebUtils;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * A Filter that requires the request to be on a specific port, and if not, redirects to the same URL on that port.
+ *
+ * @author Les Hazlewood
+ * @since Mar 30, 2009 10:46:21 AM
+ */
+public class PortFilter extends AuthorizationFilter {
+
+ protected int toPort(Object mappedValue) {
+ String[] ports = (String[]) mappedValue;
+ if (ports == null || ports.length == 0) {
+ throw new ConfigurationException("PortFilter defined, but no port was specified!");
+ }
+ if (ports.length > 1) {
+ throw new ConfigurationException("PortFilter can only be configured with a single port. You have " +
+ "configured " + ports.length + ": " + StringUtils.toString(ports));
+ }
+ return Integer.parseInt(ports[0]);
+ }
+
+ protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
+ int requiredPort = toPort(mappedValue);
+ int requestPort = request.getServerPort();
+ return requiredPort == requestPort;
+ }
+
+ /**
+ * Redirects the request to the same exact incoming URL, but with the port listed in the filter's configuration.
+ *
+ * @param request the incoming <code>ServletRequest</code>
+ * @param response the outgoing <code>ServletResponse</code>
+ * @param mappedValue the config specified for the filter in the matching request's filter chain.
+ * @return {@code false} always to force a redirect.
+ */
+ @Override
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
+
+ //just redirect to the specified port:
+ int port = toPort(mappedValue);
+
+ StringBuffer sb = new StringBuffer();
+
+ String scheme = request.getScheme();
+ if (port == 80) {
+ scheme = "http";
+ } else if (port == 443) {
+ scheme = "https";
+ }
+ sb.append(scheme).append("://");
+ sb.append(request.getServerName());
+ if (port != 80 && port != 443) {
+ sb.append(":");
+ sb.append(request.getServerPort());
+ }
+ if (request instanceof HttpServletRequest) {
+ sb.append(WebUtils.toHttp(request).getRequestURI());
+ String query = WebUtils.toHttp(request).getQueryString();
+ if ( query != null ) {
+ sb.append("?").append(query);
+ }
+ }
+
+ WebUtils.issueRedirect(request, response, sb.toString());
+
+ return false;
+ }
+}
Added: incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/SslFilter.java
URL: http://svn.apache.org/viewvc/incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/SslFilter.java?rev=760043&view=auto
==============================================================================
--- incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/SslFilter.java (added)
+++ incubator/jsecurity/trunk/web/src/main/java/org/apache/ki/web/filter/authz/SslFilter.java Mon Mar 30 16:56:57 2009
@@ -0,0 +1,27 @@
+package org.apache.ki.web.filter.authz;
+
+/**
+ * Convenience filter which requires a request to be over SSL. This filter has the same effect as of using the
+ * {@link PortFilter} with configuration defaulting to port {@code 443}. That is, these two configs are the same:
+ *
+ * <pre>
+ * /some/path/** = port[443]
+ * /some/path/** = ssl
+ * </pre>
+ *
+ * @author Les Hazlewood
+ * @since Mar 30, 2009 12:16:14 PM
+ */
+public class SslFilter extends PortFilter {
+
+ public static final int DEFAULT_SSL_PORT = 443;
+
+ @Override
+ protected int toPort(Object mappedValue) {
+ String[] ports = (String[]) mappedValue;
+ if (ports == null || ports.length == 0) {
+ return DEFAULT_SSL_PORT;
+ }
+ return super.toPort(mappedValue);
+ }
+}