1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.ui;
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
27 import org.acegisecurity.context.SecurityContextHolder;
28
29 import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken;
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
44
45
46
47
48 public class ExceptionTranslationFilterTests extends TestCase {
49
50
51
52 public ExceptionTranslationFilterTests() {
53 super();
54 }
55
56 public ExceptionTranslationFilterTests(String arg0) {
57 super(arg0);
58 }
59
60
61
62
63 public static void main(String[] args) {
64 junit.textui.TestRunner.run(ExceptionTranslationFilterTests.class);
65 }
66
67 public final void setUp() throws Exception {
68 super.setUp();
69 }
70
71 protected void tearDown() throws Exception {
72 super.tearDown();
73 SecurityContextHolder.clearContext();
74 }
75
76 public void testAccessDeniedWhenAnonymous() throws Exception {
77
78 MockHttpServletRequest request = new MockHttpServletRequest();
79 request.setServletPath("/secure/page.html");
80 request.setServerPort(80);
81 request.setScheme("http");
82 request.setServerName("www.example.com");
83 request.setContextPath("/mycontext");
84 request.setRequestURI("/mycontext/secure/page.html");
85
86
87 MockFilterChain chain = new MockFilterChain(true, false, false, false);
88
89
90
91 SecurityContextHolder.getContext().setAuthentication(
92 new AnonymousAuthenticationToken("ignored", "ignored",
93 new GrantedAuthority[] { new GrantedAuthorityImpl("IGNORED") }));
94
95
96 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
97 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
98
99 MockHttpServletResponse response = new MockHttpServletResponse();
100 filter.doFilter(request, response, chain);
101 assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
102 assertEquals("http://www.example.com/mycontext/secure/page.html", AbstractProcessingFilter
103 .obtainFullRequestUrl(request));
104 }
105
106 public void testAccessDeniedWhenNonAnonymous() throws Exception {
107
108 MockHttpServletRequest request = new MockHttpServletRequest();
109 request.setServletPath("/secure/page.html");
110
111
112 MockFilterChain chain = new MockFilterChain(true, false, false, false);
113
114
115
116 SecurityContextHolder.getContext().setAuthentication(null);
117
118
119 AccessDeniedHandlerImpl adh = new AccessDeniedHandlerImpl();
120 adh.setErrorPage("/error.jsp");
121
122
123 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
124 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
125 filter.setAccessDeniedHandler(adh);
126
127 MockHttpServletResponse response = new MockHttpServletResponse();
128 filter.doFilter(request, response, chain);
129 assertEquals(403, response.getStatus());
130 assertEquals(AccessDeniedException.class, request.getAttribute(
131 AccessDeniedHandlerImpl.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY).getClass());
132 }
133
134 public void testDoFilterWithNonHttpServletRequestDetected() throws Exception {
135 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
136
137 try {
138 filter.doFilter(null, new MockHttpServletResponse(), new MockFilterChain(false, false, false, false));
139 fail("Should have thrown ServletException");
140 }
141 catch (ServletException expected) {
142 assertEquals("HttpServletRequest required", expected.getMessage());
143 }
144 }
145
146 public void testDoFilterWithNonHttpServletResponseDetected() throws Exception {
147 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
148
149 try {
150 filter.doFilter(new MockHttpServletRequest(null, null), null, new MockFilterChain(false, false, false,
151 false));
152 fail("Should have thrown ServletException");
153 }
154 catch (ServletException expected) {
155 assertEquals("HttpServletResponse required", expected.getMessage());
156 }
157 }
158
159 public void testGettersSetters() {
160 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
161
162 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
163 assertTrue(filter.getAuthenticationEntryPoint() != null);
164
165 filter.setPortResolver(new MockPortResolver(80, 443));
166 assertTrue(filter.getPortResolver() != null);
167 }
168
169 public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWhenAuthenticationException() throws Exception {
170
171 MockHttpServletRequest request = new MockHttpServletRequest();
172 request.setServletPath("/secure/page.html");
173 request.setServerPort(80);
174 request.setScheme("http");
175 request.setServerName("www.example.com");
176 request.setContextPath("/mycontext");
177 request.setRequestURI("/mycontext/secure/page.html");
178
179
180 MockFilterChain chain = new MockFilterChain(false, true, false, false);
181
182
183 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
184 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
185 filter.setPortResolver(new MockPortResolver(80, 443));
186
187
188
189
190
191
192
193 MockHttpServletResponse response = new MockHttpServletResponse();
194 filter.doFilter(request, response, chain);
195 assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
196 assertEquals("http://www.example.com/mycontext/secure/page.html", AbstractProcessingFilter
197 .obtainFullRequestUrl(request));
198 }
199
200 public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWithExoticPortWhenAuthenticationException()
201 throws Exception {
202
203 MockHttpServletRequest request = new MockHttpServletRequest();
204 request.setServletPath("/secure/page.html");
205 request.setServerPort(8080);
206 request.setScheme("http");
207 request.setServerName("www.example.com");
208 request.setContextPath("/mycontext");
209 request.setRequestURI("/mycontext/secure/page.html");
210
211
212 MockFilterChain chain = new MockFilterChain(false, true, false, false);
213
214
215 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
216 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
217 filter.setPortResolver(new MockPortResolver(8080, 8443));
218
219
220
221
222
223
224
225 MockHttpServletResponse response = new MockHttpServletResponse();
226 filter.doFilter(request, response, chain);
227 assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
228 assertEquals("http://www.example.com:8080/mycontext/secure/page.html", AbstractProcessingFilter
229 .obtainFullRequestUrl(request));
230 }
231
232 public void testStartupDetectsMissingAuthenticationEntryPoint() throws Exception {
233 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
234
235 try {
236 filter.afterPropertiesSet();
237 fail("Should have thrown IllegalArgumentException");
238 }
239 catch (IllegalArgumentException expected) {
240 assertEquals("authenticationEntryPoint must be specified", expected.getMessage());
241 }
242 }
243
244 public void testStartupDetectsMissingPortResolver() throws Exception {
245 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
246 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
247 filter.setPortResolver(null);
248
249 try {
250 filter.afterPropertiesSet();
251 fail("Should have thrown IllegalArgumentException");
252 }
253 catch (IllegalArgumentException expected) {
254 assertEquals("portResolver must be specified", expected.getMessage());
255 }
256 }
257
258 public void testSuccessfulAccessGrant() throws Exception {
259
260 MockHttpServletRequest request = new MockHttpServletRequest();
261 request.setServletPath("/secure/page.html");
262
263
264 MockFilterChain chain = new MockFilterChain(false, false, false, false);
265
266
267 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
268 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
269
270 MockHttpServletResponse response = new MockHttpServletResponse();
271 filter.doFilter(request, response, chain);
272 }
273
274 public void testSuccessfulStartupAndShutdownDown() throws Exception {
275 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
276
277 filter.init(null);
278 filter.destroy();
279 assertTrue(true);
280 }
281
282 public void testThrowIOException() throws Exception {
283 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
284
285 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(""));
286
287
288
289
290
291
292
293 try {
294 filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain(false,
295 false, false, true));
296 fail("Should have thrown IOException");
297 }
298 catch (IOException e) {
299 assertNull("The IOException thrown should not have been wrapped", e.getCause());
300 }
301 }
302
303 public void testThrowServletException() throws Exception {
304 ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
305
306 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(""));
307
308
309
310
311
312
313
314 try {
315 filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain(false,
316 false, true, false));
317 fail("Should have thrown ServletException");
318 }
319 catch (ServletException e) {
320 assertNull("The ServletException thrown should not have been wrapped", e.getCause());
321 }
322 }
323
324
325
326
327 private class MockFilterChain implements FilterChain {
328 private boolean throwAccessDenied;
329
330 private boolean throwAuthenticationFailure;
331
332 private boolean throwIOException;
333
334 private boolean throwServletException;
335
336 public MockFilterChain(boolean throwAccessDenied, boolean throwAuthenticationFailure,
337 boolean throwServletException, boolean throwIOException) {
338 this.throwAccessDenied = throwAccessDenied;
339 this.throwAuthenticationFailure = throwAuthenticationFailure;
340 this.throwServletException = throwServletException;
341 this.throwIOException = throwIOException;
342 }
343
344 public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
345 if (throwAccessDenied) {
346 throw new AccessDeniedException("As requested");
347 }
348
349 if (throwAuthenticationFailure) {
350 throw new BadCredentialsException("As requested");
351 }
352
353 if (throwServletException) {
354 throw new ServletException("As requested");
355 }
356
357 if (throwIOException) {
358 throw new IOException("As requested");
359 }
360 }
361 }
362 }