1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.intercept.web;
17
18 import junit.framework.TestCase;
19
20 import org.acegisecurity.AccessDeniedException;
21 import org.acegisecurity.BadCredentialsException;
22 import org.acegisecurity.GrantedAuthority;
23 import org.acegisecurity.GrantedAuthorityImpl;
24 import org.acegisecurity.MockAuthenticationEntryPoint;
25 import org.acegisecurity.MockPortResolver;
26 import org.acegisecurity.context.SecurityContextHolder;
27 import org.acegisecurity.context.SecurityContextImpl;
28 import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken;
29 import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
30
31 import org.springframework.mock.web.MockHttpServletRequest;
32 import org.springframework.mock.web.MockHttpServletResponse;
33
34 import java.io.IOException;
35
36 import javax.servlet.FilterChain;
37 import javax.servlet.ServletException;
38 import javax.servlet.ServletRequest;
39 import javax.servlet.ServletResponse;
40
41
42 /***
43 * Tests {@link SecurityEnforcementFilter}.
44 *
45 * @author Ben Alex
46 * @version $Id: SecurityEnforcementFilterTests.java,v 1.16 2005/11/17 00:55:50 benalex Exp $
47 */
48 public class SecurityEnforcementFilterTests extends TestCase {
49
50
51 public SecurityEnforcementFilterTests() {
52 super();
53 }
54
55 public SecurityEnforcementFilterTests(String arg0) {
56 super(arg0);
57 }
58
59
60
61 public final void setUp() throws Exception {
62 super.setUp();
63 }
64
65 public static void main(String[] args) {
66 junit.textui.TestRunner.run(SecurityEnforcementFilterTests.class);
67 }
68
69 public void testAccessDeniedWhenAnonymous() throws Exception {
70
71 MockHttpServletRequest request = new MockHttpServletRequest();
72 request.setServletPath("/secure/page.html");
73 request.setServerPort(80);
74 request.setScheme("http");
75 request.setServerName("www.example.com");
76 request.setContextPath("/mycontext");
77 request.setRequestURI("/mycontext/secure/page.html");
78
79
80 MockFilterChain chain = new MockFilterChain(false);
81
82
83 MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(true,
84 false, false, false);
85
86
87 SecurityContextHolder.getContext().setAuthentication(new AnonymousAuthenticationToken(
88 "ignored", "ignored",
89 new GrantedAuthority[] {new GrantedAuthorityImpl("IGNORED")}));
90
91
92 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
93 filter.setFilterSecurityInterceptor(interceptor);
94 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
95 "/login.jsp"));
96
97 MockHttpServletResponse response = new MockHttpServletResponse();
98 filter.doFilter(request, response, chain);
99 assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
100 assertEquals("http://www.example.com/mycontext/secure/page.html",
101 request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY));
102 }
103
104 public void testAccessDeniedWhenNonAnonymous() throws Exception {
105
106 MockHttpServletRequest request = new MockHttpServletRequest();
107 request.setServletPath("/secure/page.html");
108
109
110 MockFilterChain chain = new MockFilterChain(false);
111
112
113 MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(true,
114 false, false, false);
115
116
117 SecurityContextHolder.getContext().setAuthentication(null);
118
119
120 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
121 filter.setFilterSecurityInterceptor(interceptor);
122 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
123 "/login.jsp"));
124
125 MockHttpServletResponse response = new MockHttpServletResponse();
126 filter.doFilter(request, response, chain);
127 assertEquals(403, response.getStatus());
128 assertEquals(AccessDeniedException.class,
129 request.getSession()
130 .getAttribute(SecurityEnforcementFilter.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY)
131 .getClass());
132 }
133
134 public void testDoFilterWithNonHttpServletRequestDetected()
135 throws Exception {
136 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
137
138 try {
139 filter.doFilter(null, new MockHttpServletResponse(),
140 new MockFilterChain());
141 fail("Should have thrown ServletException");
142 } catch (ServletException expected) {
143 assertEquals("HttpServletRequest required", expected.getMessage());
144 }
145 }
146
147 public void testDoFilterWithNonHttpServletResponseDetected()
148 throws Exception {
149 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
150
151 try {
152 filter.doFilter(new MockHttpServletRequest(null, null), null,
153 new MockFilterChain());
154 fail("Should have thrown ServletException");
155 } catch (ServletException expected) {
156 assertEquals("HttpServletResponse required", expected.getMessage());
157 }
158 }
159
160 public void testGettersSetters() {
161 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
162 filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
163 false, false, false, false));
164 assertTrue(filter.getFilterSecurityInterceptor() != null);
165
166 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
167 "/login.jsp"));
168 assertTrue(filter.getAuthenticationEntryPoint() != null);
169
170 filter.setPortResolver(new MockPortResolver(80, 443));
171 assertTrue(filter.getPortResolver() != null);
172 }
173
174 public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWhenAuthenticationException()
175 throws Exception {
176
177 MockHttpServletRequest request = new MockHttpServletRequest();
178 request.setServletPath("/secure/page.html");
179 request.setServerPort(80);
180 request.setScheme("http");
181 request.setServerName("www.example.com");
182 request.setContextPath("/mycontext");
183 request.setRequestURI("/mycontext/secure/page.html");
184
185
186 MockFilterChain chain = new MockFilterChain(false);
187
188
189 MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(false,
190 true, false, false);
191
192
193 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
194 filter.setFilterSecurityInterceptor(interceptor);
195 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
196 "/login.jsp"));
197 filter.setPortResolver(new MockPortResolver(80, 443));
198 filter.afterPropertiesSet();
199
200 MockHttpServletResponse response = new MockHttpServletResponse();
201 filter.doFilter(request, response, chain);
202 assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
203 assertEquals("http://www.example.com/mycontext/secure/page.html",
204 request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY));
205 }
206
207 public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWithExoticPortWhenAuthenticationException()
208 throws Exception {
209
210 MockHttpServletRequest request = new MockHttpServletRequest();
211 request.setServletPath("/secure/page.html");
212 request.setServerPort(8080);
213 request.setScheme("http");
214 request.setServerName("www.example.com");
215 request.setContextPath("/mycontext");
216 request.setRequestURI("/mycontext/secure/page.html");
217
218
219 MockFilterChain chain = new MockFilterChain(false);
220
221
222 MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(false,
223 true, false, false);
224
225
226 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
227 filter.setFilterSecurityInterceptor(interceptor);
228 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
229 "/login.jsp"));
230 filter.setPortResolver(new MockPortResolver(8080, 8443));
231 filter.afterPropertiesSet();
232
233 MockHttpServletResponse response = new MockHttpServletResponse();
234 filter.doFilter(request, response, chain);
235 assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
236 assertEquals("http://www.example.com:8080/mycontext/secure/page.html",
237 request.getSession().getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY));
238 }
239
240 public void testStartupDetectsMissingAuthenticationEntryPoint()
241 throws Exception {
242 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
243 filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
244 false, false, false, false));
245
246 try {
247 filter.afterPropertiesSet();
248 fail("Should have thrown IllegalArgumentException");
249 } catch (IllegalArgumentException expected) {
250 assertEquals("authenticationEntryPoint must be specified",
251 expected.getMessage());
252 }
253 }
254
255 public void testStartupDetectsMissingFilterSecurityInterceptor()
256 throws Exception {
257 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
258 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
259 "/login.jsp"));
260
261 try {
262 filter.afterPropertiesSet();
263 fail("Should have thrown IllegalArgumentException");
264 } catch (IllegalArgumentException expected) {
265 assertEquals("filterSecurityInterceptor must be specified",
266 expected.getMessage());
267 }
268 }
269
270 public void testStartupDetectsMissingPortResolver()
271 throws Exception {
272 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
273 filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
274 false, false, false, false));
275 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
276 "/login.jsp"));
277 filter.setPortResolver(null);
278
279 try {
280 filter.afterPropertiesSet();
281 fail("Should have thrown IllegalArgumentException");
282 } catch (IllegalArgumentException expected) {
283 assertEquals("portResolver must be specified", expected.getMessage());
284 }
285 }
286
287 public void testSuccessfulAccessGrant() throws Exception {
288
289 MockHttpServletRequest request = new MockHttpServletRequest();
290 request.setServletPath("/secure/page.html");
291
292
293 MockFilterChain chain = new MockFilterChain(true);
294
295
296 MockFilterSecurityInterceptor interceptor = new MockFilterSecurityInterceptor(false,
297 false, false, false);
298
299
300 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
301 filter.setFilterSecurityInterceptor(interceptor);
302 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
303 "/login.jsp"));
304
305 MockHttpServletResponse response = new MockHttpServletResponse();
306 filter.doFilter(request, response, chain);
307 }
308
309 public void testSuccessfulStartupAndShutdownDown()
310 throws Exception {
311 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
312
313 filter.init(null);
314 filter.destroy();
315 assertTrue(true);
316 }
317
318 public void testThrowIOException() throws Exception {
319 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
320
321 filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
322 false, false, false, true));
323
324 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(""));
325
326 filter.afterPropertiesSet();
327
328 try {
329 filter.doFilter(new MockHttpServletRequest(),
330 new MockHttpServletResponse(), new MockFilterChain(false));
331 fail("Should have thrown IOException");
332 } catch (IOException e) {
333 assertNull("The IOException thrown should not have been wrapped",
334 e.getCause());
335 }
336 }
337
338 public void testThrowServletException() throws Exception {
339 SecurityEnforcementFilter filter = new SecurityEnforcementFilter();
340
341 filter.setFilterSecurityInterceptor(new MockFilterSecurityInterceptor(
342 false, false, true, false));
343
344 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(""));
345
346 filter.afterPropertiesSet();
347
348 try {
349 filter.doFilter(new MockHttpServletRequest(),
350 new MockHttpServletResponse(), new MockFilterChain(false));
351 fail("Should have thrown ServletException");
352 } catch (ServletException e) {
353 assertNull("The ServletException thrown should not have been wrapped",
354 e.getCause());
355 }
356 }
357
358 protected void tearDown() throws Exception {
359 super.tearDown();
360 SecurityContextHolder.setContext(new SecurityContextImpl());
361 }
362
363
364
365 private class MockFilterChain implements FilterChain {
366 private boolean expectToProceed;
367
368 public MockFilterChain(boolean expectToProceed) {
369 this.expectToProceed = expectToProceed;
370 }
371
372 private MockFilterChain() {
373 super();
374 }
375
376 public void doFilter(ServletRequest request, ServletResponse response)
377 throws IOException, ServletException {
378 if (expectToProceed) {
379 assertTrue(true);
380 } else {
381 fail("Did not expect filter chain to proceed");
382 }
383 }
384 }
385
386 private class MockFilterSecurityInterceptor
387 extends FilterSecurityInterceptor {
388 private boolean throwAccessDenied;
389 private boolean throwAuthenticationFailure;
390 private boolean throwIOException;
391 private boolean throwServletException;
392
393 public MockFilterSecurityInterceptor(boolean throwAccessDenied,
394 boolean throwAuthenticationFailure, boolean throwServletException,
395 boolean throwIOException) {
396 this.throwAccessDenied = throwAccessDenied;
397 this.throwAuthenticationFailure = throwAuthenticationFailure;
398 this.throwServletException = throwServletException;
399 this.throwIOException = throwIOException;
400 }
401
402 public void invoke(FilterInvocation fi) throws Throwable {
403 if (throwAccessDenied) {
404 throw new AccessDeniedException("As requested");
405 }
406
407 if (throwAuthenticationFailure) {
408 throw new BadCredentialsException("As requested");
409 }
410
411 if (throwServletException) {
412 throw new ServletException("As requested");
413 }
414
415 if (throwIOException) {
416 throw new IOException("As requested");
417 }
418
419 fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
420 }
421 }
422 }