1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.ui.basicauth;
17
18 import junit.framework.TestCase;
19
20 import org.acegisecurity.MockAuthenticationEntryPoint;
21 import org.acegisecurity.MockAuthenticationManager;
22 import org.acegisecurity.MockFilterConfig;
23 import org.acegisecurity.context.SecurityContextHolder;
24 import org.acegisecurity.context.SecurityContextImpl;
25 import org.acegisecurity.userdetails.UserDetails;
26
27 import org.apache.commons.codec.binary.Base64;
28
29 import org.springframework.context.ApplicationContext;
30 import org.springframework.context.support.ClassPathXmlApplicationContext;
31
32 import org.springframework.mock.web.MockHttpServletRequest;
33 import org.springframework.mock.web.MockHttpServletResponse;
34 import org.springframework.mock.web.MockHttpSession;
35
36 import java.io.IOException;
37
38 import javax.servlet.Filter;
39 import javax.servlet.FilterChain;
40 import javax.servlet.FilterConfig;
41 import javax.servlet.ServletException;
42 import javax.servlet.ServletRequest;
43 import javax.servlet.ServletResponse;
44
45
46 /***
47 * Tests {@link BasicProcessingFilter}.
48 *
49 * @author Ben Alex
50 * @version $Id: BasicProcessingFilterTests.java,v 1.14 2005/11/29 13:10:09 benalex Exp $
51 */
52 public class BasicProcessingFilterTests extends TestCase {
53
54
55 public BasicProcessingFilterTests() {
56 super();
57 }
58
59 public BasicProcessingFilterTests(String arg0) {
60 super(arg0);
61 }
62
63
64
65 public static void main(String[] args) {
66 junit.textui.TestRunner.run(BasicProcessingFilterTests.class);
67 }
68
69 public void testDoFilterWithNonHttpServletRequestDetected()
70 throws Exception {
71 BasicProcessingFilter filter = new BasicProcessingFilter();
72
73 try {
74 filter.doFilter(null, new MockHttpServletResponse(),
75 new MockFilterChain());
76 fail("Should have thrown ServletException");
77 } catch (ServletException expected) {
78 assertEquals("Can only process HttpServletRequest",
79 expected.getMessage());
80 }
81 }
82
83 public void testDoFilterWithNonHttpServletResponseDetected()
84 throws Exception {
85 BasicProcessingFilter filter = new BasicProcessingFilter();
86
87 try {
88 filter.doFilter(new MockHttpServletRequest(null, null), null,
89 new MockFilterChain());
90 fail("Should have thrown ServletException");
91 } catch (ServletException expected) {
92 assertEquals("Can only process HttpServletResponse",
93 expected.getMessage());
94 }
95 }
96
97 public void testFilterIgnoresRequestsContainingNoAuthorizationHeader()
98 throws Exception {
99
100 MockHttpServletRequest request = new MockHttpServletRequest();
101 request.setServletPath("/some_file.html");
102
103
104 ApplicationContext ctx = new ClassPathXmlApplicationContext(
105 "org/acegisecurity/ui/basicauth/filtertest-valid.xml");
106 BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
107 "basicProcessingFilter");
108
109
110 MockFilterConfig config = new MockFilterConfig();
111
112
113 MockFilterChain chain = new MockFilterChain(true);
114 MockHttpServletResponse response = new MockHttpServletResponse();
115
116
117 executeFilterInContainerSimulator(config, filter, request, response,
118 chain);
119
120 assertNull(SecurityContextHolder.getContext().getAuthentication());
121 }
122
123 public void testGettersSetters() {
124 BasicProcessingFilter filter = new BasicProcessingFilter();
125 filter.setAuthenticationManager(new MockAuthenticationManager());
126 assertTrue(filter.getAuthenticationManager() != null);
127
128 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
129 "sx"));
130 assertTrue(filter.getAuthenticationEntryPoint() != null);
131 }
132
133 public void testInvalidBasicAuthorizationTokenIsIgnored()
134 throws Exception {
135
136 String token = "NOT_A_VALID_TOKEN_AS_MISSING_COLON";
137 MockHttpServletRequest request = new MockHttpServletRequest();
138 request.addHeader("Authorization",
139 "Basic " + new String(Base64.encodeBase64(token.getBytes())));
140 request.setServletPath("/some_file.html");
141 request.setSession(new MockHttpSession());
142
143
144 ApplicationContext ctx = new ClassPathXmlApplicationContext(
145 "org/acegisecurity/ui/basicauth/filtertest-valid.xml");
146 BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
147 "basicProcessingFilter");
148
149
150 MockFilterConfig config = new MockFilterConfig();
151
152
153 MockFilterChain chain = new MockFilterChain(true);
154 MockHttpServletResponse response = new MockHttpServletResponse();
155
156
157 executeFilterInContainerSimulator(config, filter, request, response,
158 chain);
159
160 assertNull(SecurityContextHolder.getContext().getAuthentication());
161 }
162
163 public void testNormalOperation() throws Exception {
164
165 String token = "marissa:koala";
166 MockHttpServletRequest request = new MockHttpServletRequest();
167 request.addHeader("Authorization",
168 "Basic " + new String(Base64.encodeBase64(token.getBytes())));
169 request.setServletPath("/some_file.html");
170 request.setSession(new MockHttpSession());
171
172
173 ApplicationContext ctx = new ClassPathXmlApplicationContext(
174 "org/acegisecurity/ui/basicauth/filtertest-valid.xml");
175 BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
176 "basicProcessingFilter");
177
178
179 MockFilterConfig config = new MockFilterConfig();
180
181
182 MockFilterChain chain = new MockFilterChain(true);
183 MockHttpServletResponse response = new MockHttpServletResponse();
184
185
186 assertNull(SecurityContextHolder.getContext().getAuthentication());
187 executeFilterInContainerSimulator(config, filter, request, response,
188 chain);
189
190 assertNotNull(SecurityContextHolder.getContext().getAuthentication());
191 assertEquals("marissa",
192 ((UserDetails) SecurityContextHolder.getContext().getAuthentication()
193 .getPrincipal()).getUsername());
194 }
195
196 public void testOtherAuthorizationSchemeIsIgnored()
197 throws Exception {
198
199 MockHttpServletRequest request = new MockHttpServletRequest();
200 request.addHeader("Authorization", "SOME_OTHER_AUTHENTICATION_SCHEME");
201 request.setServletPath("/some_file.html");
202
203
204 ApplicationContext ctx = new ClassPathXmlApplicationContext(
205 "org/acegisecurity/ui/basicauth/filtertest-valid.xml");
206 BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
207 "basicProcessingFilter");
208
209
210 MockFilterConfig config = new MockFilterConfig();
211
212
213 MockFilterChain chain = new MockFilterChain(true);
214 MockHttpServletResponse response = new MockHttpServletResponse();
215
216
217 executeFilterInContainerSimulator(config, filter, request, response,
218 chain);
219
220 assertNull(SecurityContextHolder.getContext().getAuthentication());
221 }
222
223 public void testStartupDetectsMissingAuthenticationEntryPoint()
224 throws Exception {
225 try {
226 BasicProcessingFilter filter = new BasicProcessingFilter();
227 filter.setAuthenticationManager(new MockAuthenticationManager());
228 filter.afterPropertiesSet();
229 fail("Should have thrown IllegalArgumentException");
230 } catch (IllegalArgumentException expected) {
231 assertEquals("An AuthenticationEntryPoint is required",
232 expected.getMessage());
233 }
234 }
235
236 public void testStartupDetectsMissingAuthenticationManager()
237 throws Exception {
238 try {
239 BasicProcessingFilter filter = new BasicProcessingFilter();
240 filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(
241 "x"));
242 filter.afterPropertiesSet();
243 fail("Should have thrown IllegalArgumentException");
244 } catch (IllegalArgumentException expected) {
245 assertEquals("An AuthenticationManager is required",
246 expected.getMessage());
247 }
248 }
249
250 public void testSuccessLoginThenFailureLoginResultsInSessionLoosingToken()
251 throws Exception {
252
253 String token = "marissa:koala";
254 MockHttpServletRequest request = new MockHttpServletRequest();
255 request.addHeader("Authorization",
256 "Basic " + new String(Base64.encodeBase64(token.getBytes())));
257 request.setServletPath("/some_file.html");
258 request.setSession(new MockHttpSession());
259
260
261 ApplicationContext ctx = new ClassPathXmlApplicationContext(
262 "org/acegisecurity/ui/basicauth/filtertest-valid.xml");
263 BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
264 "basicProcessingFilter");
265
266
267 MockFilterConfig config = new MockFilterConfig();
268
269
270 MockFilterChain chain = new MockFilterChain(true);
271 MockHttpServletResponse response = new MockHttpServletResponse();
272
273
274 executeFilterInContainerSimulator(config, filter, request, response,
275 chain);
276
277 assertNotNull(SecurityContextHolder.getContext().getAuthentication());
278 assertEquals("marissa",
279 ((UserDetails) SecurityContextHolder.getContext().getAuthentication()
280 .getPrincipal()).getUsername());
281
282
283
284 token = "otherUser:WRONG_PASSWORD";
285 request = new MockHttpServletRequest();
286 request.addHeader("Authorization",
287 "Basic " + new String(Base64.encodeBase64(token.getBytes())));
288 request.setServletPath("/some_file.html");
289 request.setSession(new MockHttpSession());
290
291
292 chain = new MockFilterChain(false);
293 response = new MockHttpServletResponse();
294
295
296 executeFilterInContainerSimulator(config, filter, request, response,
297 chain);
298
299 assertNull(SecurityContextHolder.getContext().getAuthentication());
300 assertEquals(401, response.getStatus());
301 }
302
303 public void testWrongPasswordReturnsForbidden() throws Exception {
304
305 String token = "marissa:WRONG_PASSWORD";
306 MockHttpServletRequest request = new MockHttpServletRequest();
307 request.addHeader("Authorization",
308 "Basic " + new String(Base64.encodeBase64(token.getBytes())));
309 request.setServletPath("/some_file.html");
310 request.setSession(new MockHttpSession());
311
312
313 ApplicationContext ctx = new ClassPathXmlApplicationContext(
314 "org/acegisecurity/ui/basicauth/filtertest-valid.xml");
315 BasicProcessingFilter filter = (BasicProcessingFilter) ctx.getBean(
316 "basicProcessingFilter");
317
318
319 MockFilterConfig config = new MockFilterConfig();
320
321
322 MockFilterChain chain = new MockFilterChain(false);
323 MockHttpServletResponse response = new MockHttpServletResponse();
324
325
326 executeFilterInContainerSimulator(config, filter, request, response,
327 chain);
328
329 assertNull(SecurityContextHolder.getContext().getAuthentication());
330 assertEquals(401, response.getStatus());
331 }
332
333 protected void setUp() throws Exception {
334 super.setUp();
335 SecurityContextHolder.setContext(new SecurityContextImpl());
336 }
337
338 protected void tearDown() throws Exception {
339 super.tearDown();
340 SecurityContextHolder.setContext(new SecurityContextImpl());
341 }
342
343 private void executeFilterInContainerSimulator(FilterConfig filterConfig,
344 Filter filter, ServletRequest request, ServletResponse response,
345 FilterChain filterChain) throws ServletException, IOException {
346 filter.init(filterConfig);
347 filter.doFilter(request, response, filterChain);
348 filter.destroy();
349 }
350
351
352
353 private class MockFilterChain implements FilterChain {
354 private boolean expectToProceed;
355
356 public MockFilterChain(boolean expectToProceed) {
357 this.expectToProceed = expectToProceed;
358 }
359
360 private MockFilterChain() {
361 super();
362 }
363
364 public void doFilter(ServletRequest request, ServletResponse response)
365 throws IOException, ServletException {
366 if (expectToProceed) {
367 assertTrue(true);
368 } else {
369 fail("Did not expect filter chain to proceed");
370 }
371 }
372 }
373 }