1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.intercept.web;
17
18 import java.io.IOException;
19 import java.util.Iterator;
20
21 import javax.servlet.FilterChain;
22 import javax.servlet.ServletException;
23 import javax.servlet.ServletRequest;
24 import javax.servlet.ServletResponse;
25
26 import junit.framework.TestCase;
27
28 import org.acegisecurity.AccessDecisionManager;
29 import org.acegisecurity.AccessDeniedException;
30 import org.acegisecurity.Authentication;
31 import org.acegisecurity.ConfigAttribute;
32 import org.acegisecurity.ConfigAttributeDefinition;
33 import org.acegisecurity.GrantedAuthority;
34 import org.acegisecurity.GrantedAuthorityImpl;
35 import org.acegisecurity.MockAccessDecisionManager;
36 import org.acegisecurity.MockApplicationContext;
37 import org.acegisecurity.MockAuthenticationManager;
38 import org.acegisecurity.MockRunAsManager;
39 import org.acegisecurity.RunAsManager;
40 import org.acegisecurity.SecurityConfig;
41 import org.acegisecurity.context.SecurityContextHolder;
42 import org.acegisecurity.context.SecurityContextImpl;
43 import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
44 import org.springframework.mock.web.MockHttpServletRequest;
45 import org.springframework.mock.web.MockHttpServletResponse;
46
47
48 /***
49 * Tests {@link FilterSecurityInterceptor}.
50 *
51 * @author Ben Alex
52 * @version $Id: FilterSecurityInterceptorTests.java,v 1.12 2005/11/30 01:23:35 benalex Exp $
53 */
54 public class FilterSecurityInterceptorTests extends TestCase {
55
56
57 public FilterSecurityInterceptorTests() {
58 super();
59 }
60
61 public FilterSecurityInterceptorTests(String arg0) {
62 super(arg0);
63 }
64
65
66
67 public final void setUp() throws Exception {
68 super.setUp();
69 }
70
71 public static void main(String[] args) {
72 junit.textui.TestRunner.run(FilterSecurityInterceptorTests.class);
73 }
74
75 public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass()
76 throws Exception {
77 FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
78 interceptor.setAuthenticationManager(new MockAuthenticationManager());
79 interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
80 interceptor.setRunAsManager(new MockRunAsManager());
81
82 interceptor.setAccessDecisionManager(new AccessDecisionManager() {
83 public boolean supports(Class clazz) {
84 return false;
85 }
86
87 public boolean supports(ConfigAttribute attribute) {
88 return true;
89 }
90
91 public void decide(Authentication authentication,
92 Object object, ConfigAttributeDefinition config)
93 throws AccessDeniedException {
94 throw new UnsupportedOperationException(
95 "mock method not implemented");
96 }
97 });
98
99 try {
100 interceptor.afterPropertiesSet();
101 fail("Should have thrown IllegalArgumentException");
102 } catch (IllegalArgumentException expected) {
103 assertEquals("AccessDecisionManager does not support secure object class: class org.acegisecurity.intercept.web.FilterInvocation",
104 expected.getMessage());
105 }
106 }
107
108 public void testEnsuresRunAsManagerSupportsFilterInvocationClass()
109 throws Exception {
110 FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
111 interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
112 interceptor.setAuthenticationManager(new MockAuthenticationManager());
113 interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
114
115 interceptor.setRunAsManager(new RunAsManager() {
116 public boolean supports(Class clazz) {
117 return false;
118 }
119
120 public boolean supports(ConfigAttribute attribute) {
121 return true;
122 }
123
124 public Authentication buildRunAs(
125 Authentication authentication, Object object,
126 ConfigAttributeDefinition config) {
127 throw new UnsupportedOperationException(
128 "mock method not implemented");
129 }
130 });
131
132 try {
133 interceptor.afterPropertiesSet();
134 fail("Should have thrown IllegalArgumentException");
135 } catch (IllegalArgumentException expected) {
136 assertEquals("RunAsManager does not support secure object class: class org.acegisecurity.intercept.web.FilterInvocation",
137 expected.getMessage());
138 }
139 }
140
141 public void testHttpsInvocationReflectsPortNumber()
142 throws Throwable {
143
144 FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
145 interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
146 interceptor.setAuthenticationManager(new MockAuthenticationManager());
147 interceptor.setRunAsManager(new MockRunAsManager());
148 interceptor.setApplicationEventPublisher(MockApplicationContext.getContext());
149
150
151 ConfigAttributeDefinition def = new ConfigAttributeDefinition();
152 def.addConfigAttribute(new SecurityConfig("MOCK_OK"));
153
154 MockFilterInvocationDefinitionMap mockSource = new MockFilterInvocationDefinitionMap("/secure/page.html",
155 def);
156 interceptor.setObjectDefinitionSource(mockSource);
157
158
159 MockFilterChain chain = new MockFilterChain(true);
160
161
162 MockHttpServletResponse response = new MockHttpServletResponse();
163 MockHttpServletRequest request = new MockHttpServletRequest();
164 request.setServletPath("/secure/page.html");
165 request.setScheme("https");
166 request.setServerPort(443);
167
168
169 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
170 "Password",
171 new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_OK")});
172 SecurityContextHolder.getContext().setAuthentication(token);
173
174
175 FilterInvocation fi = new FilterInvocation(request, response, chain);
176 interceptor.invoke(fi);
177
178
179 SecurityContextHolder.setContext(new SecurityContextImpl());
180 }
181
182 public void testNormalStartupAndGetter() throws Exception {
183 FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
184 interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
185 interceptor.setAuthenticationManager(new MockAuthenticationManager());
186
187 RegExpBasedFilterInvocationDefinitionMap fidp = new RegExpBasedFilterInvocationDefinitionMap();
188 interceptor.setObjectDefinitionSource(fidp);
189 interceptor.setRunAsManager(new MockRunAsManager());
190 interceptor.afterPropertiesSet();
191 assertTrue(true);
192 assertEquals(fidp, interceptor.getObjectDefinitionSource());
193 }
194
195 /***
196 * We just test invocation works in a success event. There is no need to
197 * test access denied events as the abstract parent enforces that logic,
198 * which is extensively tested separately.
199 *
200 */
201 public void testSuccessfulInvocation() throws Throwable {
202
203 FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
204 interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
205 interceptor.setAuthenticationManager(new MockAuthenticationManager());
206 interceptor.setRunAsManager(new MockRunAsManager());
207 interceptor.setApplicationEventPublisher(MockApplicationContext.getContext());
208
209
210 ConfigAttributeDefinition def = new ConfigAttributeDefinition();
211 def.addConfigAttribute(new SecurityConfig("MOCK_OK"));
212
213 MockFilterInvocationDefinitionMap mockSource = new MockFilterInvocationDefinitionMap("/secure/page.html",
214 def);
215 interceptor.setObjectDefinitionSource(mockSource);
216
217
218 MockFilterChain chain = new MockFilterChain(true);
219
220
221 MockHttpServletResponse response = new MockHttpServletResponse();
222 MockHttpServletRequest request = new MockHttpServletRequest();
223 request.setServletPath("/secure/page.html");
224
225
226 UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
227 "Password",
228 new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_OK")});
229 SecurityContextHolder.getContext().setAuthentication(token);
230
231
232 FilterInvocation fi = new FilterInvocation(request, response, chain);
233 interceptor.invoke(fi);
234
235
236 SecurityContextHolder.setContext(new SecurityContextImpl());
237 }
238
239
240
241 private class MockFilterChain implements FilterChain {
242 private boolean expectToProceed;
243
244 public MockFilterChain(boolean expectToProceed) {
245 this.expectToProceed = expectToProceed;
246 }
247
248 private MockFilterChain() {
249 super();
250 }
251
252 public void doFilter(ServletRequest request, ServletResponse response)
253 throws IOException, ServletException {
254 if (expectToProceed) {
255 assertTrue(true);
256 } else {
257 fail("Did not expect filter chain to proceed");
258 }
259 }
260 }
261
262 private class MockFilterInvocationDefinitionMap
263 implements FilterInvocationDefinitionSource {
264 private ConfigAttributeDefinition toReturn;
265 private String servletPath;
266
267 public MockFilterInvocationDefinitionMap(String servletPath,
268 ConfigAttributeDefinition toReturn) {
269 this.servletPath = servletPath;
270 this.toReturn = toReturn;
271 }
272
273 private MockFilterInvocationDefinitionMap() {
274 super();
275 }
276
277 public ConfigAttributeDefinition getAttributes(Object object)
278 throws IllegalArgumentException {
279 FilterInvocation fi = (FilterInvocation) object;
280
281 if (servletPath.equals(fi.getHttpRequest().getServletPath())) {
282 return toReturn;
283 } else {
284 return null;
285 }
286 }
287
288 public Iterator getConfigAttributeDefinitions() {
289 return null;
290 }
291
292 public boolean supports(Class clazz) {
293 return true;
294 }
295 }
296 }