001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.intercept.web;
017:
018: import org.acegisecurity.intercept.AbstractSecurityInterceptor;
019: import org.acegisecurity.intercept.InterceptorStatusToken;
020: import org.acegisecurity.intercept.ObjectDefinitionSource;
021:
022: import java.io.IOException;
023:
024: import javax.servlet.Filter;
025: import javax.servlet.FilterChain;
026: import javax.servlet.FilterConfig;
027: import javax.servlet.ServletException;
028: import javax.servlet.ServletRequest;
029: import javax.servlet.ServletResponse;
030:
031: /**
032: * Performs security handling of HTTP resources via a filter implementation.<p>The
033: * <code>ObjectDefinitionSource</code> required by this security interceptor is of type {@link
034: * FilterInvocationDefinitionSource}.</p>
035: * <P>Refer to {@link AbstractSecurityInterceptor} for details on the workflow.</p>
036: *
037: * @author Ben Alex
038: * @version $Id: FilterSecurityInterceptor.java 1496 2006-05-23 13:38:33Z benalex $
039: */
040: public class FilterSecurityInterceptor extends
041: AbstractSecurityInterceptor implements Filter {
042: //~ Static fields/initializers =====================================================================================
043:
044: private static final String FILTER_APPLIED = "__acegi_filterSecurityInterceptor_filterApplied";
045:
046: //~ Instance fields ================================================================================================
047:
048: private FilterInvocationDefinitionSource objectDefinitionSource;
049: private boolean observeOncePerRequest = true;
050:
051: //~ Methods ========================================================================================================
052:
053: /**
054: * Not used (we rely on IoC container lifecycle services instead)
055: */
056: public void destroy() {
057: }
058:
059: /**
060: * Method that is actually called by the filter chain. Simply delegates to the {@link
061: * #invoke(FilterInvocation)} method.
062: *
063: * @param request the servlet request
064: * @param response the servlet response
065: * @param chain the filter chain
066: *
067: * @throws IOException if the filter chain fails
068: * @throws ServletException if the filter chain fails
069: */
070: public void doFilter(ServletRequest request,
071: ServletResponse response, FilterChain chain)
072: throws IOException, ServletException {
073: FilterInvocation fi = new FilterInvocation(request, response,
074: chain);
075: invoke(fi);
076: }
077:
078: public FilterInvocationDefinitionSource getObjectDefinitionSource() {
079: return this .objectDefinitionSource;
080: }
081:
082: public Class getSecureObjectClass() {
083: return FilterInvocation.class;
084: }
085:
086: /**
087: * Not used (we rely on IoC container lifecycle services instead)
088: *
089: * @param arg0 ignored
090: *
091: * @throws ServletException never thrown
092: */
093: public void init(FilterConfig arg0) throws ServletException {
094: }
095:
096: public void invoke(FilterInvocation fi) throws IOException,
097: ServletException {
098: if ((fi.getRequest() != null)
099: && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
100: && observeOncePerRequest) {
101: // filter already applied to this request and user wants us to observce
102: // once-per-request handling, so don't re-do security checking
103: fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
104: } else {
105: // first time this request being called, so perform security checking
106: if (fi.getRequest() != null) {
107: fi.getRequest().setAttribute(FILTER_APPLIED,
108: Boolean.TRUE);
109: }
110:
111: InterceptorStatusToken token = super .beforeInvocation(fi);
112:
113: try {
114: fi.getChain().doFilter(fi.getRequest(),
115: fi.getResponse());
116: } finally {
117: super .afterInvocation(token, null);
118: }
119: }
120: }
121:
122: /**
123: * Indicates whether once-per-request handling will be observed. By default this is <code>true</code>,
124: * meaning the <code>FilterSecurityInterceptor</code> will only execute once-per-request. Sometimes users may wish
125: * it to execute more than once per request, such as when JSP forwards are being used and filter security is
126: * desired on each included fragment of the HTTP request.
127: *
128: * @return <code>true</code> (the default) if once-per-request is honoured, otherwise <code>false</code> if
129: * <code>FilterSecurityInterceptor</code> will enforce authorizations for each and every fragment of the
130: * HTTP request.
131: */
132: public boolean isObserveOncePerRequest() {
133: return observeOncePerRequest;
134: }
135:
136: public ObjectDefinitionSource obtainObjectDefinitionSource() {
137: return this .objectDefinitionSource;
138: }
139:
140: public void setObjectDefinitionSource(
141: FilterInvocationDefinitionSource newSource) {
142: this .objectDefinitionSource = newSource;
143: }
144:
145: public void setObserveOncePerRequest(boolean observeOncePerRequest) {
146: this.observeOncePerRequest = observeOncePerRequest;
147: }
148: }
|