From 9771b7817affba011f71c2d5e10df34f27da9bc4 Mon Sep 17 00:00:00 2001
From: Ben Alex AuthenticationEntryPoint
to be called, allowing the
* principal to authenticate with a stronger level of authentication.
*
- * End users should only use this class to configure their HTTP security
- * configuration in an application context. They should not attempt to
- * invoke the FilterSecurityInterceptor
except as a standard bean
- * registration in an application context. At runtime, this class will provide
- * services to web applications via the {@link SecurityEnforcementFilter}.
- *
* The ObjectDefinitionSource
required by this security
* interceptor is of type {@link FilterInvocationDefinitionSource}.
@@ -43,7 +44,8 @@ import org.acegisecurity.intercept.ObjectDefinitionSource;
* @author Ben Alex
* @version $Id$
*/
-public class FilterSecurityInterceptor extends AbstractSecurityInterceptor {
+public class FilterSecurityInterceptor extends AbstractSecurityInterceptor
+ implements Filter {
//~ Static fields/initializers =============================================
private static final String FILTER_APPLIED = "__acegi_filterSecurityInterceptor_filterApplied";
@@ -55,41 +57,47 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor {
//~ Methods ================================================================
- public void setObjectDefinitionSource(
- FilterInvocationDefinitionSource newSource) {
- this.objectDefinitionSource = newSource;
+ /**
+ * Not used (we rely on IoC container lifecycle services instead)
+ */
+ public void destroy() {}
+
+ /**
+ * Method that is actually called by the filter chain. Simply delegates to
+ * the {@link #invoke(FilterInvocation)} method.
+ *
+ * @param request the servlet request
+ * @param response the servlet response
+ * @param chain the filter chain
+ *
+ * @throws IOException if the filter chain fails
+ * @throws ServletException if the filter chain fails
+ */
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+ FilterInvocation fi = new FilterInvocation(request, response, chain);
+ invoke(fi);
}
public FilterInvocationDefinitionSource getObjectDefinitionSource() {
return this.objectDefinitionSource;
}
- public void setObserveOncePerRequest(boolean observeOncePerRequest) {
- this.observeOncePerRequest = observeOncePerRequest;
- }
-
- /**
- * Indicates whether once-per-request handling will be observed. By default
- * this is true
, meaning the
- * FilterSecurityInterceptor
will only execute
- * once-per-request. Sometimes users may wish it to execute more than once
- * per request, such as when JSP forwards are being used and filter
- * security is desired on each included fragment of the HTTP request.
- *
- * @return true
(the default) if once-per-request is honoured,
- * otherwise false
if
- * FilterSecurityInterceptor
will enforce
- * authorizations for each and every fragment of the HTTP request.
- */
- public boolean isObserveOncePerRequest() {
- return observeOncePerRequest;
- }
-
public Class getSecureObjectClass() {
return FilterInvocation.class;
}
- public void invoke(FilterInvocation fi) throws Throwable {
+ /**
+ * Not used (we rely on IoC container lifecycle services instead)
+ *
+ * @param arg0 ignored
+ *
+ * @throws ServletException never thrown
+ */
+ public void init(FilterConfig arg0) throws ServletException {}
+
+ public void invoke(FilterInvocation fi)
+ throws IOException, ServletException {
if ((fi.getRequest() != null)
&& (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
&& observeOncePerRequest) {
@@ -112,7 +120,33 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor {
}
}
+ /**
+ * Indicates whether once-per-request handling will be observed. By default
+ * this is true
, meaning the
+ * FilterSecurityInterceptor
will only execute
+ * once-per-request. Sometimes users may wish it to execute more than once
+ * per request, such as when JSP forwards are being used and filter
+ * security is desired on each included fragment of the HTTP request.
+ *
+ * @return true
(the default) if once-per-request is honoured,
+ * otherwise false
if
+ * FilterSecurityInterceptor
will enforce
+ * authorizations for each and every fragment of the HTTP request.
+ */
+ public boolean isObserveOncePerRequest() {
+ return observeOncePerRequest;
+ }
+
public ObjectDefinitionSource obtainObjectDefinitionSource() {
return this.objectDefinitionSource;
}
+
+ public void setObjectDefinitionSource(
+ FilterInvocationDefinitionSource newSource) {
+ this.objectDefinitionSource = newSource;
+ }
+
+ public void setObserveOncePerRequest(boolean observeOncePerRequest) {
+ this.observeOncePerRequest = observeOncePerRequest;
+ }
}
diff --git a/core/src/main/java/org/acegisecurity/intercept/web/AuthenticationEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/AuthenticationEntryPoint.java
similarity index 94%
rename from core/src/main/java/org/acegisecurity/intercept/web/AuthenticationEntryPoint.java
rename to core/src/main/java/org/acegisecurity/ui/AuthenticationEntryPoint.java
index 103ff0b285..3c16e1c35e 100644
--- a/core/src/main/java/org/acegisecurity/intercept/web/AuthenticationEntryPoint.java
+++ b/core/src/main/java/org/acegisecurity/ui/AuthenticationEntryPoint.java
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-package org.acegisecurity.intercept.web;
+package org.acegisecurity.ui;
import org.acegisecurity.AuthenticationException;
@@ -25,7 +25,7 @@ import javax.servlet.ServletResponse;
/**
- * Used by {@link SecurityEnforcementFilter} to commence an authentication
+ * Used by {@link ExceptionTranslationFilter} to commence an authentication
* scheme.
*
* @author Ben Alex
diff --git a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java b/core/src/main/java/org/acegisecurity/ui/ExceptionTranslationFilter.java
similarity index 70%
rename from core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java
rename to core/src/main/java/org/acegisecurity/ui/ExceptionTranslationFilter.java
index 136ffb0c8f..8b99519ab7 100644
--- a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java
+++ b/core/src/main/java/org/acegisecurity/ui/ExceptionTranslationFilter.java
@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 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.
@@ -12,15 +12,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.acegisecurity.intercept.web;
+
+package org.acegisecurity.ui;
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationTrustResolver;
import org.acegisecurity.AuthenticationTrustResolverImpl;
import org.acegisecurity.InsufficientAuthenticationException;
+
import org.acegisecurity.context.SecurityContextHolder;
-import org.acegisecurity.ui.AbstractProcessingFilter;
+
+import org.acegisecurity.intercept.web.FilterInvocation;
+
import org.acegisecurity.util.PortResolver;
import org.acegisecurity.util.PortResolverImpl;
@@ -44,20 +48,22 @@ import javax.servlet.http.HttpServletResponse;
/**
- * Wraps requests to the {@link FilterSecurityInterceptor}.
- *
+ * Handles any AccessDeniedException
and
+ * AuthenticationException
thrown within the filter chain.
+ *
*
- * This filter is necessary because it provides the bridge between incoming
- * requests and the FilterSecurityInterceptor
instance.
+ * This filter is necessary because it provides the bridge between Java
+ * exceptions and HTTP responses. It is solely concerned with maintaining the
+ * user interface. This filter does not do any actual security enforcement.
*
* If an {@link AuthenticationException} is detected, the filter will launch
* the authenticationEntryPoint
. This allows common handling of
* authentication failures originating from any subclass of {@link
* org.acegisecurity.intercept.AbstractSecurityInterceptor}.
*
* If an {@link AccessDeniedException} is detected, the filter will determine * whether or not the user is an anonymous user. If they are an anonymous @@ -70,18 +76,13 @@ import javax.servlet.http.HttpServletResponse; * trace etc). Again, this allows common access denied handling irrespective * of the originating security interceptor. *
- * + * ** To use this filter, it is necessary to specify the following properties: *
- * + * *filterSecurityInterceptor
indicates the
- * FilterSecurityInterceptor
to delegate HTTP security decisions
- * to.
- * authenticationEntryPoint
indicates the handler that should
* commence the authentication process if an
* AuthenticationException
is detected. Note that this may also
@@ -92,7 +93,7 @@ import javax.servlet.http.HttpServletResponse;
* request was received on.
*
* Do not use this class directly. Instead configure
* web.xml
to use the {@link
@@ -103,83 +104,30 @@ import javax.servlet.http.HttpServletResponse;
* @author colin sampaleanu
* @version $Id$
*/
-public class SecurityEnforcementFilter implements Filter, InitializingBean {
- private static final Log logger = LogFactory.getLog(SecurityEnforcementFilter.class);
+public class ExceptionTranslationFilter implements Filter, InitializingBean {
+ //~ Static fields/initializers =============================================
+
+ private static final Log logger = LogFactory.getLog(ExceptionTranslationFilter.class);
public static final String ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY = "ACEGI_SECURITY_403_EXCEPTION";
+
+ //~ Instance fields ========================================================
+
private AuthenticationEntryPoint authenticationEntryPoint;
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
- private FilterSecurityInterceptor filterSecurityInterceptor;
private PortResolver portResolver = new PortResolverImpl();
private boolean createSessionAllowed = true;
- public void setAuthenticationEntryPoint(
- AuthenticationEntryPoint authenticationEntryPoint) {
- this.authenticationEntryPoint = authenticationEntryPoint;
- }
-
- public AuthenticationEntryPoint getAuthenticationEntryPoint() {
- return authenticationEntryPoint;
- }
-
- public void setAuthenticationTrustResolver(
- AuthenticationTrustResolver authenticationTrustResolver) {
- this.authenticationTrustResolver = authenticationTrustResolver;
- }
-
- /**
- * If true
, indicates that SecurityEnforcementFilter
is permitted
- * to store the target URL and exception information in the HttpSession
(the
- * default). In situations where you do not wish to unnecessarily create HttpSession
s
- * - because the user agent will know the failed URL, such as with BASIC or Digest authentication
- * - you may wish to set this property to false
. Remember to also set the
- * {@link org.acegisecurity.context.HttpSessionContextIntegrationFilter#allowSessionCreation}
- * to false
if you set this property to false
.
- *
- * @return true
if the HttpSession
will be used to store information
- * about the failed request, false
if the HttpSession
will not be
- * used
- */
- public boolean isCreateSessionAllowed() {
- return createSessionAllowed;
- }
-
- public void setCreateSessionAllowed(boolean createSessionAllowed) {
- this.createSessionAllowed = createSessionAllowed;
- }
-
- public AuthenticationTrustResolver getAuthenticationTrustResolver() {
- return authenticationTrustResolver;
- }
-
- public void setFilterSecurityInterceptor(
- FilterSecurityInterceptor filterSecurityInterceptor) {
- this.filterSecurityInterceptor = filterSecurityInterceptor;
- }
-
- public FilterSecurityInterceptor getFilterSecurityInterceptor() {
- return filterSecurityInterceptor;
- }
-
- public void setPortResolver(PortResolver portResolver) {
- this.portResolver = portResolver;
- }
-
- public PortResolver getPortResolver() {
- return portResolver;
- }
+ //~ Methods ================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(authenticationEntryPoint,
"authenticationEntryPoint must be specified");
- Assert.notNull(filterSecurityInterceptor,
- "filterSecurityInterceptor must be specified");
Assert.notNull(portResolver, "portResolver must be specified");
Assert.notNull(authenticationTrustResolver,
"authenticationTrustResolver must be specified");
}
- public void destroy() {
- }
+ public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
@@ -191,10 +139,8 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean {
throw new ServletException("HttpServletResponse required");
}
- FilterInvocation fi = new FilterInvocation(request, response, chain);
-
try {
- filterSecurityInterceptor.invoke(fi);
+ chain.doFilter(request, response);
if (logger.isDebugEnabled()) {
logger.debug("Chain processed normally");
@@ -205,16 +151,16 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean {
authentication);
}
- sendStartAuthentication(fi, authentication);
+ sendStartAuthentication(request, response, chain, authentication);
} catch (AccessDeniedException accessDenied) {
if (authenticationTrustResolver.isAnonymous(
- SecurityContextHolder.getContext().getAuthentication())) {
+ SecurityContextHolder.getContext().getAuthentication())) {
if (logger.isDebugEnabled()) {
logger.debug("Access is denied (user is anonymous); redirecting to authentication entry point",
accessDenied);
}
- sendStartAuthentication(fi,
+ sendStartAuthentication(request, response, chain,
new InsufficientAuthenticationException(
"Full authentication is required to access this resource"));
} else {
@@ -223,7 +169,7 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean {
accessDenied);
}
- sendAccessDeniedError(fi, accessDenied);
+ sendAccessDeniedError(request, response, chain, accessDenied);
}
} catch (ServletException e) {
throw e;
@@ -234,56 +180,112 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean {
}
}
- public void init(FilterConfig filterConfig) throws ServletException {
+ public AuthenticationEntryPoint getAuthenticationEntryPoint() {
+ return authenticationEntryPoint;
}
- protected void sendAccessDeniedError(FilterInvocation fi,
+ public AuthenticationTrustResolver getAuthenticationTrustResolver() {
+ return authenticationTrustResolver;
+ }
+
+ public PortResolver getPortResolver() {
+ return portResolver;
+ }
+
+ public void init(FilterConfig filterConfig) throws ServletException {}
+
+ /**
+ * If true
, indicates that
+ * SecurityEnforcementFilter
is permitted to store the target
+ * URL and exception information in the HttpSession
(the
+ * default). In situations where you do not wish to unnecessarily create
+ * HttpSession
s - because the user agent will know the failed
+ * URL, such as with BASIC or Digest authentication - you may wish to set
+ * this property to false
. Remember to also set the {@link
+ * org.acegisecurity.context.HttpSessionContextIntegrationFilter#allowSessionCreation}
+ * to false
if you set this property to false
.
+ *
+ * @return true
if the HttpSession
will be used
+ * to store information about the failed request,
+ * false
if the HttpSession
will not be
+ * used
+ */
+ public boolean isCreateSessionAllowed() {
+ return createSessionAllowed;
+ }
+
+ protected void sendAccessDeniedError(ServletRequest request,
+ ServletResponse response, FilterChain chain,
AccessDeniedException accessDenied)
throws ServletException, IOException {
if (createSessionAllowed) {
- ((HttpServletRequest) fi.getRequest()).getSession().setAttribute(ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY,
+ ((HttpServletRequest) request).getSession()
+ .setAttribute(ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY,
accessDenied);
}
- ((HttpServletResponse) fi.getResponse()).sendError(HttpServletResponse.SC_FORBIDDEN,
+ ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN,
accessDenied.getMessage()); // 403
}
- protected void sendStartAuthentication(FilterInvocation fi,
+ protected void sendStartAuthentication(ServletRequest request,
+ ServletResponse response, FilterChain chain,
AuthenticationException reason) throws ServletException, IOException {
- HttpServletRequest request = (HttpServletRequest) fi.getRequest();
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
- int port = portResolver.getServerPort(request);
+ int port = portResolver.getServerPort(httpRequest);
boolean includePort = true;
- if ("http".equals(request.getScheme().toLowerCase()) && (port == 80)) {
+ if ("http".equals(httpRequest.getScheme().toLowerCase())
+ && (port == 80)) {
includePort = false;
}
- if ("https".equals(request.getScheme().toLowerCase()) && (port == 443)) {
+ if ("https".equals(httpRequest.getScheme().toLowerCase())
+ && (port == 443)) {
includePort = false;
}
- String targetUrl = request.getScheme() + "://" +
- request.getServerName() + ((includePort) ? (":" + port) : "") +
- request.getContextPath() + fi.getRequestUrl();
+ String targetUrl = httpRequest.getScheme() + "://"
+ + httpRequest.getServerName() + ((includePort) ? (":" + port) : "")
+ + httpRequest.getContextPath()
+ + new FilterInvocation(request, response, chain).getRequestUrl();
if (logger.isDebugEnabled()) {
logger.debug(
- "Authentication entry point being called; target URL added to Session: " +
- targetUrl);
+ "Authentication entry point being called; target URL added to Session: "
+ + targetUrl);
}
if (createSessionAllowed) {
- ((HttpServletRequest) request).getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY,
+ httpRequest.getSession()
+ .setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY,
targetUrl);
}
-
+
// SEC-112: Clear the SecurityContextHolder's Authentication, as the
// existing Authentication is no longer considered valid
SecurityContextHolder.getContext().setAuthentication(null);
- authenticationEntryPoint.commence(request,
- (HttpServletResponse) fi.getResponse(), reason);
+ authenticationEntryPoint.commence(httpRequest,
+ (HttpServletResponse) response, reason);
+ }
+
+ public void setAuthenticationEntryPoint(
+ AuthenticationEntryPoint authenticationEntryPoint) {
+ this.authenticationEntryPoint = authenticationEntryPoint;
+ }
+
+ public void setAuthenticationTrustResolver(
+ AuthenticationTrustResolver authenticationTrustResolver) {
+ this.authenticationTrustResolver = authenticationTrustResolver;
+ }
+
+ public void setCreateSessionAllowed(boolean createSessionAllowed) {
+ this.createSessionAllowed = createSessionAllowed;
+ }
+
+ public void setPortResolver(PortResolver portResolver) {
+ this.portResolver = portResolver;
}
}
diff --git a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java
index 18eda7de59..784baa31d0 100644
--- a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java
+++ b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilter.java
@@ -19,8 +19,8 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.context.SecurityContextHolder;
-import org.acegisecurity.intercept.web.AuthenticationEntryPoint;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import org.acegisecurity.ui.AuthenticationEntryPoint;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.apache.commons.codec.binary.Base64;
diff --git a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java
index 35a40d4c70..0c6f9a2e1f 100644
--- a/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java
+++ b/core/src/main/java/org/acegisecurity/ui/basicauth/BasicProcessingFilterEntryPoint.java
@@ -16,7 +16,7 @@
package org.acegisecurity.ui.basicauth;
import org.acegisecurity.AuthenticationException;
-import org.acegisecurity.intercept.web.AuthenticationEntryPoint;
+import org.acegisecurity.ui.AuthenticationEntryPoint;
import org.springframework.beans.factory.InitializingBean;
diff --git a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java
index ee635fbfae..1373b38360 100644
--- a/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java
+++ b/core/src/main/java/org/acegisecurity/ui/cas/CasProcessingFilterEntryPoint.java
@@ -16,7 +16,7 @@
package org.acegisecurity.ui.cas;
import org.acegisecurity.AuthenticationException;
-import org.acegisecurity.intercept.web.AuthenticationEntryPoint;
+import org.acegisecurity.ui.AuthenticationEntryPoint;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
diff --git a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java
index a681210ed3..d429e9d86d 100644
--- a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java
+++ b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java
@@ -84,7 +84,7 @@ import org.springframework.util.StringUtils;
*
*
* If authentication fails, an {@link - * org.acegisecurity.intercept.web.AuthenticationEntryPoint + * org.acegisecurity.ui.AuthenticationEntryPoint * AuthenticationEntryPoint} implementation is called. This must always be * {@link DigestProcessingFilterEntryPoint}, which will prompt the user to * authenticate again via Digest authentication. diff --git a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java index a71086ceb3..0087c6171e 100644 --- a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilterEntryPoint.java @@ -16,7 +16,7 @@ package org.acegisecurity.ui.digestauth; import org.acegisecurity.AuthenticationException; -import org.acegisecurity.intercept.web.AuthenticationEntryPoint; +import org.acegisecurity.ui.AuthenticationEntryPoint; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java index 376c158991..be78ca2c28 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPoint.java @@ -15,7 +15,7 @@ package org.acegisecurity.ui.webapp; import org.acegisecurity.AuthenticationException; -import org.acegisecurity.intercept.web.AuthenticationEntryPoint; +import org.acegisecurity.ui.AuthenticationEntryPoint; import org.acegisecurity.util.PortMapper; import org.acegisecurity.util.PortMapperImpl; import org.acegisecurity.util.PortResolver; diff --git a/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java b/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java index ed71c024a3..16b5f321d9 100644 --- a/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java +++ b/core/src/main/java/org/acegisecurity/ui/x509/X509ProcessingFilterEntryPoint.java @@ -15,7 +15,7 @@ package org.acegisecurity.ui.x509; -import org.acegisecurity.intercept.web.AuthenticationEntryPoint; +import org.acegisecurity.ui.AuthenticationEntryPoint; import org.acegisecurity.AuthenticationException; import javax.servlet.ServletRequest; @@ -42,7 +42,7 @@ import org.apache.commons.logging.LogFactory; * * @author Luke Taylor * @version $Id$ - * @see org.acegisecurity.intercept.web.SecurityEnforcementFilter + * @see org.acegisecurity.ui.ExceptionTranslationFilter */ public class X509ProcessingFilterEntryPoint implements AuthenticationEntryPoint { //~ Static fields/initializers ============================================= diff --git a/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java b/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java index af470e1049..22ba68b03e 100644 --- a/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java +++ b/core/src/test/java/org/acegisecurity/MockAuthenticationEntryPoint.java @@ -15,7 +15,7 @@ package org.acegisecurity; -import org.acegisecurity.intercept.web.AuthenticationEntryPoint; +import org.acegisecurity.ui.AuthenticationEntryPoint; import java.io.IOException; diff --git a/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java b/core/src/test/java/org/acegisecurity/ui/ExceptionTranslationFilterTests.java similarity index 63% rename from core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java rename to core/src/test/java/org/acegisecurity/ui/ExceptionTranslationFilterTests.java index 5112bb155a..8c14fa972b 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/ExceptionTranslationFilterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 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. @@ -13,7 +13,14 @@ * limitations under the License. */ -package org.acegisecurity.intercept.web; +package org.acegisecurity.ui; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import junit.framework.TestCase; @@ -27,43 +34,40 @@ import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextImpl; import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken; import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter; - import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - /** - * Tests {@link SecurityEnforcementFilter}. + * Tests {@link ExceptionTranslationFilter}. * * @author Ben Alex * @version $Id$ */ -public class SecurityEnforcementFilterTests extends TestCase { +public class ExceptionTranslationFilterTests extends TestCase { //~ Constructors =========================================================== - public SecurityEnforcementFilterTests() { + public ExceptionTranslationFilterTests() { super(); } - public SecurityEnforcementFilterTests(String arg0) { + public ExceptionTranslationFilterTests(String arg0) { super(arg0); } //~ Methods ================================================================ + public static void main(String[] args) { + junit.textui.TestRunner.run(ExceptionTranslationFilterTests.class); + } + public final void setUp() throws Exception { super.setUp(); } - public static void main(String[] args) { - junit.textui.TestRunner.run(SecurityEnforcementFilterTests.class); + protected void tearDown() throws Exception { + super.tearDown(); + SecurityContextHolder.setContext(new SecurityContextImpl()); } public void testAccessDeniedWhenAnonymous() throws Exception { @@ -76,21 +80,17 @@ public class SecurityEnforcementFilterTests extends TestCase { request.setContextPath("/mycontext"); request.setRequestURI("/mycontext/secure/page.html"); - // Setup our expectation that the filter chain will not be invoked, as access is denied - MockFilterChain chain = new MockFilterChain(false); - - // Setup the FilterSecurityInterceptor thrown an access denied exception - MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(true, - false, false, false); + // Setup the FilterChain to thrown an access denied exception + MockFilterChain chain = new MockFilterChain(true, false, false, false); // Setup SecurityContextHolder, as filter needs to check if user is anonymous - SecurityContextHolder.getContext().setAuthentication(new AnonymousAuthenticationToken( + SecurityContextHolder.getContext() + .setAuthentication(new AnonymousAuthenticationToken( "ignored", "ignored", new GrantedAuthority[] {new GrantedAuthorityImpl("IGNORED")})); // Test - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(interceptor); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( "/login.jsp")); @@ -98,7 +98,8 @@ public class SecurityEnforcementFilterTests extends TestCase { filter.doFilter(request, response, chain); assertEquals("/mycontext/login.jsp", response.getRedirectedUrl()); assertEquals("http://www.example.com/mycontext/secure/page.html", - request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY)); + request.getSession() + .getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY)); } public void testAccessDeniedWhenNonAnonymous() throws Exception { @@ -106,19 +107,14 @@ public class SecurityEnforcementFilterTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setServletPath("/secure/page.html"); - // Setup our expectation that the filter chain will not be invoked, as access is denied - MockFilterChain chain = new MockFilterChain(false); - - // Setup the FilterSecurityInterceptor thrown an access denied exception - MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(true, - false, false, false); + // Setup the FilterChain to thrown an access denied exception + MockFilterChain chain = new MockFilterChain(true, false, false, false); // Setup SecurityContextHolder, as filter needs to check if user is anonymous SecurityContextHolder.getContext().setAuthentication(null); // Test - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(interceptor); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( "/login.jsp")); @@ -127,17 +123,17 @@ public class SecurityEnforcementFilterTests extends TestCase { assertEquals(403, response.getStatus()); assertEquals(AccessDeniedException.class, request.getSession() - .getAttribute(SecurityEnforcementFilter.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY) + .getAttribute(ExceptionTranslationFilter.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY) .getClass()); } public void testDoFilterWithNonHttpServletRequestDetected() throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); try { filter.doFilter(null, new MockHttpServletResponse(), - new MockFilterChain()); + new MockFilterChain(false, false, false, false)); fail("Should have thrown ServletException"); } catch (ServletException expected) { assertEquals("HttpServletRequest required", expected.getMessage()); @@ -146,11 +142,11 @@ public class SecurityEnforcementFilterTests extends TestCase { public void testDoFilterWithNonHttpServletResponseDetected() throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); try { filter.doFilter(new MockHttpServletRequest(null, null), null, - new MockFilterChain()); + new MockFilterChain(false, false, false, false)); fail("Should have thrown ServletException"); } catch (ServletException expected) { assertEquals("HttpServletResponse required", expected.getMessage()); @@ -158,10 +154,7 @@ public class SecurityEnforcementFilterTests extends TestCase { } public void testGettersSetters() { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor( - false, false, false, false)); - assertTrue(filter.getFilterSecurityInterceptor() != null); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( "/login.jsp")); @@ -182,16 +175,11 @@ public class SecurityEnforcementFilterTests extends TestCase { request.setContextPath("/mycontext"); request.setRequestURI("/mycontext/secure/page.html"); - // Setup our expectation that the filter chain will not be invoked, as access is denied - MockFilterChain chain = new MockFilterChain(false); - - // Setup the FilterSecurityInterceptor thrown an authentication failure exceptions - MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(false, - true, false, false); + // Setup the FilterChain to thrown an authentication failure exception + MockFilterChain chain = new MockFilterChain(false, true, false, false); // Test - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(interceptor); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( "/login.jsp")); filter.setPortResolver(new MockPortResolver(80, 443)); @@ -201,7 +189,8 @@ public class SecurityEnforcementFilterTests extends TestCase { filter.doFilter(request, response, chain); assertEquals("/mycontext/login.jsp", response.getRedirectedUrl()); assertEquals("http://www.example.com/mycontext/secure/page.html", - request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY)); + request.getSession() + .getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY)); } public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWithExoticPortWhenAuthenticationException() @@ -215,16 +204,11 @@ public class SecurityEnforcementFilterTests extends TestCase { request.setContextPath("/mycontext"); request.setRequestURI("/mycontext/secure/page.html"); - // Setup our expectation that the filter chain will not be invoked, as access is denied - MockFilterChain chain = new MockFilterChain(false); - - // Setup the FilterSecurityInterceptor thrown an authentication failure exceptions - MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(false, - true, false, false); + // Setup the FilterChain to thrown an authentication failure exception + MockFilterChain chain = new MockFilterChain(false, true, false, false); // Test - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(interceptor); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( "/login.jsp")); filter.setPortResolver(new MockPortResolver(8080, 8443)); @@ -234,14 +218,13 @@ public class SecurityEnforcementFilterTests extends TestCase { filter.doFilter(request, response, chain); assertEquals("/mycontext/login.jsp", response.getRedirectedUrl()); assertEquals("http://www.example.com:8080/mycontext/secure/page.html", - request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY)); + request.getSession() + .getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY)); } public void testStartupDetectsMissingAuthenticationEntryPoint() throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor( - false, false, false, false)); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); try { filter.afterPropertiesSet(); @@ -252,26 +235,9 @@ public class SecurityEnforcementFilterTests extends TestCase { } } - public void testStartupDetectsMissingFilterSecurityInterceptor() - throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( - "/login.jsp")); - - try { - filter.afterPropertiesSet(); - fail("Should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - assertEquals("filterSecurityInterceptor must be specified", - expected.getMessage()); - } - } - public void testStartupDetectsMissingPortResolver() throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor( - false, false, false, false)); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( "/login.jsp")); filter.setPortResolver(null); @@ -289,16 +255,11 @@ public class SecurityEnforcementFilterTests extends TestCase { MockHttpServletRequest request = new MockHttpServletRequest(); request.setServletPath("/secure/page.html"); - // Setup our expectation that the filter chain will be invoked, as access is granted - MockFilterChain chain = new MockFilterChain(true); - - // Setup the FilterSecurityInterceptor to not thrown any exceptions - MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(false, - false, false, false); + // Setup the FilterChain to thrown no exceptions + MockFilterChain chain = new MockFilterChain(false, false, false, false); // Test - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - filter.setFilterSecurityInterceptor(interceptor); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint( "/login.jsp")); @@ -308,7 +269,7 @@ public class SecurityEnforcementFilterTests extends TestCase { public void testSuccessfulStartupAndShutdownDown() throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.init(null); filter.destroy(); @@ -316,10 +277,7 @@ public class SecurityEnforcementFilterTests extends TestCase { } public void testThrowIOException() throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - - filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor( - false, false, false, true)); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("")); @@ -327,7 +285,8 @@ public class SecurityEnforcementFilterTests extends TestCase { try { filter.doFilter(new MockHttpServletRequest(), - new MockHttpServletResponse(), new MockFilterChain(false)); + new MockHttpServletResponse(), + new MockFilterChain(false, false, false, true)); fail("Should have thrown IOException"); } catch (IOException e) { assertNull("The IOException thrown should not have been wrapped", @@ -336,10 +295,7 @@ public class SecurityEnforcementFilterTests extends TestCase { } public void testThrowServletException() throws Exception { - SecurityEnforcementFilter filter = new SecurityEnforcementFilter(); - - filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor( - false, false, true, false)); + ExceptionTranslationFilter filter = new ExceptionTranslationFilter(); filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("")); @@ -347,7 +303,8 @@ public class SecurityEnforcementFilterTests extends TestCase { try { filter.doFilter(new MockHttpServletRequest(), - new MockHttpServletResponse(), new MockFilterChain(false)); + new MockHttpServletResponse(), + new MockFilterChain(false, false, true, false)); fail("Should have thrown ServletException"); } catch (ServletException e) { assertNull("The ServletException thrown should not have been wrapped", @@ -355,42 +312,15 @@ public class SecurityEnforcementFilterTests extends TestCase { } } - protected void tearDown() throws Exception { - super.tearDown(); - SecurityContextHolder.setContext(new SecurityContextImpl()); - } - //~ Inner Classes ========================================================== private class MockFilterChain implements FilterChain { - private boolean expectToProceed; - - public MockFilterChain(boolean expectToProceed) { - this.expectToProceed = expectToProceed; - } - - private MockFilterChain() { - super(); - } - - public void doFilter(ServletRequest request, ServletResponse response) - throws IOException, ServletException { - if (expectToProceed) { - assertTrue(true); - } else { - fail("Did not expect filter chain to proceed"); - } - } - } - - private class MockFilterSecurityInterceptor - extends FilterSecurityInterceptor { private boolean throwAccessDenied; private boolean throwAuthenticationFailure; private boolean throwIOException; private boolean throwServletException; - public MockFilterSecurityInterceptor(boolean throwAccessDenied, + public MockFilterChain(boolean throwAccessDenied, boolean throwAuthenticationFailure, boolean throwServletException, boolean throwIOException) { this.throwAccessDenied = throwAccessDenied; @@ -399,7 +329,8 @@ public class SecurityEnforcementFilterTests extends TestCase { this.throwIOException = throwIOException; } - public void invoke(FilterInvocation fi) throws Throwable { + public void doFilter(ServletRequest request, ServletResponse response) + throws IOException, ServletException { if (throwAccessDenied) { throw new AccessDeniedException("As requested"); } @@ -415,8 +346,6 @@ public class SecurityEnforcementFilterTests extends TestCase { if (throwIOException) { throw new IOException("As requested"); } - - fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } } } diff --git a/doc/xdocs/upgrade/upgrade-090-100.html b/doc/xdocs/upgrade/upgrade-090-100.html index 496613416a..8de426546c 100644 --- a/doc/xdocs/upgrade/upgrade-090-100.html +++ b/doc/xdocs/upgrade/upgrade-090-100.html @@ -48,6 +48,24 @@ applications: point to an implementation of org.acegisecurity.providers.ProviderManager. +