1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.securechannel;
17
18 import org.acegisecurity.ConfigAttribute;
19 import org.acegisecurity.ConfigAttributeDefinition;
20 import org.acegisecurity.intercept.web.FilterInvocation;
21 import org.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import org.springframework.beans.factory.InitializingBean;
27 import org.springframework.util.Assert;
28
29 import java.io.IOException;
30
31 import java.util.HashSet;
32 import java.util.Iterator;
33 import java.util.Set;
34
35 import javax.servlet.Filter;
36 import javax.servlet.FilterChain;
37 import javax.servlet.FilterConfig;
38 import javax.servlet.ServletException;
39 import javax.servlet.ServletRequest;
40 import javax.servlet.ServletResponse;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43
44
45 /***
46 * Ensures a web request is delivered over the required channel.
47 *
48 * <p>
49 * Internally uses a {@link FilterInvocation} to represent the request, so that
50 * the <code>FilterInvocation</code>-related property editors and lookup
51 * classes can be used.
52 * </p>
53 *
54 * <P>
55 * Delegates the actual channel security decisions and necessary actions to the
56 * configured {@link ChannelDecisionManager}. If a response is committed by
57 * the <code>ChannelDecisionManager</code>, the filter chain will not proceed.
58 * </p>
59 *
60 * <P>
61 * <B>Do not use this class directly.</B> Instead configure
62 * <code>web.xml</code> to use the {@link
63 * org.acegisecurity.util.FilterToBeanProxy}.
64 * </p>
65 *
66 * @author Ben Alex
67 * @version $Id: ChannelProcessingFilter.java,v 1.5 2005/11/17 00:55:50 benalex Exp $
68 */
69 public class ChannelProcessingFilter implements InitializingBean, Filter {
70
71
72 private static final Log logger = LogFactory.getLog(ChannelProcessingFilter.class);
73
74
75
76 private ChannelDecisionManager channelDecisionManager;
77 private FilterInvocationDefinitionSource filterInvocationDefinitionSource;
78
79
80
81 public void setChannelDecisionManager(
82 ChannelDecisionManager channelDecisionManager) {
83 this.channelDecisionManager = channelDecisionManager;
84 }
85
86 public ChannelDecisionManager getChannelDecisionManager() {
87 return channelDecisionManager;
88 }
89
90 public void setFilterInvocationDefinitionSource(
91 FilterInvocationDefinitionSource filterInvocationDefinitionSource) {
92 this.filterInvocationDefinitionSource = filterInvocationDefinitionSource;
93 }
94
95 public FilterInvocationDefinitionSource getFilterInvocationDefinitionSource() {
96 return filterInvocationDefinitionSource;
97 }
98
99 public void afterPropertiesSet() throws Exception {
100 Assert.notNull(filterInvocationDefinitionSource, "filterInvocationDefinitionSource must be specified");
101 Assert.notNull(channelDecisionManager, "channelDecisionManager must be specified");
102
103 Iterator iter = this.filterInvocationDefinitionSource
104 .getConfigAttributeDefinitions();
105
106 if (iter == null) {
107 if (logger.isWarnEnabled()) {
108 logger.warn("Could not validate configuration attributes as the FilterInvocationDefinitionSource did not return a ConfigAttributeDefinition Iterator");
109 }
110
111 return;
112 }
113
114 Set set = new HashSet();
115
116 while (iter.hasNext()) {
117 ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter
118 .next();
119 Iterator attributes = def.getConfigAttributes();
120
121 while (attributes.hasNext()) {
122 ConfigAttribute attr = (ConfigAttribute) attributes.next();
123
124 if (!this.channelDecisionManager.supports(attr)) {
125 set.add(attr);
126 }
127 }
128 }
129
130 if (set.size() == 0) {
131 if (logger.isInfoEnabled()) {
132 logger.info("Validated configuration attributes");
133 }
134 } else {
135 throw new IllegalArgumentException("Unsupported configuration attributes: " + set.toString());
136 }
137 }
138
139 public void destroy() {}
140
141 public void doFilter(ServletRequest request, ServletResponse response,
142 FilterChain chain) throws IOException, ServletException {
143 if (!(request instanceof HttpServletRequest)) {
144 throw new ServletException("HttpServletRequest required");
145 }
146
147 if (!(response instanceof HttpServletResponse)) {
148 throw new ServletException("HttpServletResponse required");
149 }
150
151 FilterInvocation fi = new FilterInvocation(request, response, chain);
152 ConfigAttributeDefinition attr = this.filterInvocationDefinitionSource
153 .getAttributes(fi);
154
155 if (attr != null) {
156 if (logger.isDebugEnabled()) {
157 logger.debug("Request: " + fi.getFullRequestUrl()
158 + "; ConfigAttributes: " + attr.toString());
159 }
160
161 channelDecisionManager.decide(fi, attr);
162
163 if (fi.getResponse().isCommitted()) {
164 return;
165 }
166 }
167
168 chain.doFilter(request, response);
169 }
170
171 public void init(FilterConfig filterConfig) throws ServletException {}
172 }