1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.context;
17
18 import junit.framework.TestCase;
19
20 import org.acegisecurity.Authentication;
21 import org.acegisecurity.GrantedAuthority;
22 import org.acegisecurity.GrantedAuthorityImpl;
23 import org.acegisecurity.MockFilterConfig;
24
25 import org.acegisecurity.adapters.PrincipalAcegiUserToken;
26 import org.jmock.Mock;
27
28 import org.springframework.mock.web.MockHttpServletRequest;
29 import org.springframework.mock.web.MockHttpServletResponse;
30
31 import java.io.IOException;
32
33 import javax.servlet.Filter;
34 import javax.servlet.FilterChain;
35 import javax.servlet.FilterConfig;
36 import javax.servlet.ServletException;
37 import javax.servlet.ServletRequest;
38 import javax.servlet.ServletResponse;
39
40
41
42
43
44
45
46
47 public class HttpSessionContextIntegrationFilterTests extends TestCase {
48
49
50 public HttpSessionContextIntegrationFilterTests() {
51 }
52
53 public HttpSessionContextIntegrationFilterTests(String arg0) {
54 super(arg0);
55 }
56
57
58
59 private static void executeFilterInContainerSimulator(
60 FilterConfig filterConfig, Filter filter, ServletRequest request,
61 ServletResponse response, FilterChain filterChain)
62 throws ServletException, IOException {
63 filter.init(filterConfig);
64 filter.doFilter(request, response, filterChain);
65 filter.destroy();
66 }
67
68 public void testDetectsIncompatibleSessionProperties() throws Exception {
69 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
70
71 try {
72 filter.setAllowSessionCreation(false);
73 filter.setForceEagerSessionCreation(true);
74 filter.afterPropertiesSet();
75 fail("Shown have thrown IllegalArgumentException");
76 } catch (IllegalArgumentException expected) {
77 assertTrue(true);
78 }
79
80 filter.setAllowSessionCreation(true);
81 filter.afterPropertiesSet();
82 assertTrue(true);
83 }
84
85 public void testDetectsMissingOrInvalidContext() throws Exception {
86 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
87
88 try {
89 filter.setContext(null);
90 filter.afterPropertiesSet();
91 fail("Shown have thrown IllegalArgumentException");
92 } catch (IllegalArgumentException expected) {
93 assertTrue(true);
94 }
95
96 try {
97 filter.setContext(Integer.class);
98 assertEquals(Integer.class, filter.getContext());
99 filter.afterPropertiesSet();
100 fail("Shown have thrown IllegalArgumentException");
101 } catch (IllegalArgumentException expected) {
102 assertTrue(true);
103 }
104 }
105
106 public void testExceptionWithinFilterChainStillClearsSecurityContextHolder() throws Exception {
107
108 PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken(
109 "key",
110 "someone",
111 "password",
112 new GrantedAuthority[] { new GrantedAuthorityImpl("SOME_ROLE") },
113 null);
114
115
116 SecurityContext sc = new SecurityContextImpl();
117 sc.setAuthentication(sessionPrincipal);
118
119
120 MockHttpServletRequest request = new MockHttpServletRequest();
121 request.getSession().setAttribute(
122 HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
123 sc);
124
125 MockHttpServletResponse response = new MockHttpServletResponse();
126 FilterChain chain = new MockFilterChain(sessionPrincipal, null,
127 new IOException());
128
129
130 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
131 filter.setContext(SecurityContextImpl.class);
132 filter.afterPropertiesSet();
133
134
135 try {
136 executeFilterInContainerSimulator(new MockFilterConfig(), filter,
137 request, response, chain);
138 fail("We should have received the IOException thrown inside the filter chain here");
139 } catch (IOException ioe) {
140 assertTrue(true);
141 }
142
143
144
145 assertEquals(new SecurityContextImpl(), SecurityContextHolder.getContext());
146 assertNull("Should have cleared FILTER_APPLIED",
147 request.getAttribute(HttpSessionContextIntegrationFilter.FILTER_APPLIED));
148 }
149
150 public void testExistingContextContentsCopiedIntoContextHolderFromSessionAndChangesToContextCopiedBackToSession()
151 throws Exception {
152
153 PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken(
154 "key",
155 "someone",
156 "password",
157 new GrantedAuthority[] { new GrantedAuthorityImpl("SOME_ROLE") },
158 null);
159
160
161
162 PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken(
163 "key", "someone", "password",
164 new GrantedAuthority[] { new GrantedAuthorityImpl(
165 "SOME_DIFFERENT_ROLE") }, null);
166
167
168 SecurityContext sc = new SecurityContextImpl();
169 sc.setAuthentication(sessionPrincipal);
170
171
172 MockHttpServletRequest request = new MockHttpServletRequest();
173 request.getSession().setAttribute(
174 HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
175 sc);
176
177 MockHttpServletResponse response = new MockHttpServletResponse();
178 FilterChain chain = new MockFilterChain(sessionPrincipal,
179 updatedPrincipal, null);
180
181
182 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
183 filter.setContext(SecurityContextImpl.class);
184 filter.afterPropertiesSet();
185
186
187 executeFilterInContainerSimulator(new MockFilterConfig(), filter,
188 request, response, chain);
189
190
191 SecurityContext context = (SecurityContext) request.getSession().getAttribute(
192 HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
193 assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication());
194 }
195
196 public void testHttpSessionCreatedWhenContextHolderChanges() throws Exception {
197
198 PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken(
199 "key", "someone", "password",
200 new GrantedAuthority[] { new GrantedAuthorityImpl(
201 "SOME_DIFFERENT_ROLE") }, null);
202
203
204 MockHttpServletRequest request = new MockHttpServletRequest();
205 MockHttpServletResponse response = new MockHttpServletResponse();
206 FilterChain chain = new MockFilterChain(null, updatedPrincipal, null);
207
208
209 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
210 filter.setContext(SecurityContextImpl.class);
211
212
213
214 executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain);
215
216
217 SecurityContext context = (SecurityContext) request.getSession(false).getAttribute(
218 HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
219 assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication());
220 }
221
222 public void testHttpSessionEagerlyCreatedWhenDirected() throws Exception {
223
224 MockHttpServletRequest request = new MockHttpServletRequest(null, null);
225 MockHttpServletResponse response = new MockHttpServletResponse();
226 FilterChain chain = new MockFilterChain(null, null, null);
227
228
229 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
230 filter.setContext(SecurityContextImpl.class);
231 filter.setForceEagerSessionCreation(true);
232 filter.afterPropertiesSet();
233
234
235 executeFilterInContainerSimulator(new MockFilterConfig(), filter,
236 request, response, chain);
237
238
239 assertNotNull(request.getSession(false));
240 }
241
242 public void testHttpSessionNotCreatedUnlessContextHolderChanges() throws Exception {
243
244 MockHttpServletRequest request = new MockHttpServletRequest(null, null);
245 MockHttpServletResponse response = new MockHttpServletResponse();
246 FilterChain chain = new MockFilterChain(null, null, null);
247
248
249 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
250 filter.setContext(SecurityContextImpl.class);
251 filter.afterPropertiesSet();
252
253
254 executeFilterInContainerSimulator(new MockFilterConfig(), filter,
255 request, response, chain);
256
257
258 assertNull(request.getSession(false));
259 }
260
261 public void testHttpSessionWithNonContextInWellKnownLocationIsOverwritten() throws Exception {
262
263
264 PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken(
265 "key", "someone", "password",
266 new GrantedAuthority[] { new GrantedAuthorityImpl(
267 "SOME_DIFFERENT_ROLE") }, null);
268
269
270 MockHttpServletRequest request = new MockHttpServletRequest();
271 request.getSession().setAttribute(
272 HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
273 "NOT_A_CONTEXT_OBJECT");
274
275 MockHttpServletResponse response = new MockHttpServletResponse();
276 FilterChain chain = new MockFilterChain(null, updatedPrincipal, null);
277
278
279 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
280 filter.setContext(SecurityContextImpl.class);
281 filter.afterPropertiesSet();
282
283
284 executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain);
285
286
287 SecurityContext context = (SecurityContext) request.getSession().getAttribute(
288 HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
289 assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication());
290 }
291
292 public void testConcurrentThreadsLazilyChangeFilterAppliedValueToTrue() throws Exception {
293 PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken(
294 "key",
295 "someone",
296 "password",
297 new GrantedAuthority[] { new GrantedAuthorityImpl("SOME_ROLE") },
298 null);
299
300
301 SecurityContext sc = new SecurityContextImpl();
302 sc.setAuthentication(sessionPrincipal);
303
304 MockHttpServletRequest request = new MockHttpServletRequest();
305 request.getSession().setAttribute(
306 HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
307 sc);
308 MockHttpServletResponse response = new MockHttpServletResponse();
309
310
311 HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
312 filter.setContext(SecurityContextImpl.class);
313 filter.afterPropertiesSet();
314
315 for (int i = 0; i < 3; i++) {
316 ThreadRunner runner = new ThreadRunner(request, response, filter,
317 new MockFilterChain(sessionPrincipal, null, null));
318 runner.start();
319 }
320
321 }
322
323
324
325
326 private class MockFilterChain extends TestCase implements FilterChain {
327 private Authentication changeContextHolder;
328 private Authentication expectedOnContextHolder;
329 private IOException toThrowDuringChain;
330
331 public MockFilterChain(Authentication expectedOnContextHolder,
332 Authentication changeContextHolder,
333 IOException toThrowDuringChain) {
334 this.expectedOnContextHolder = expectedOnContextHolder;
335 this.changeContextHolder = changeContextHolder;
336 this.toThrowDuringChain = toThrowDuringChain;
337 }
338
339 public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException {
340 if (expectedOnContextHolder != null) {
341 assertEquals(expectedOnContextHolder, SecurityContextHolder.getContext().getAuthentication());
342 }
343
344 if (changeContextHolder != null) {
345 SecurityContext sc = SecurityContextHolder.getContext();
346 sc.setAuthentication(changeContextHolder);
347 SecurityContextHolder.setContext(sc);
348 }
349
350 if (toThrowDuringChain != null) {
351 throw toThrowDuringChain;
352 }
353
354 }
355 }
356
357 private static class ThreadRunner extends Thread {
358 private MockHttpServletRequest request;
359 private MockHttpServletResponse response;
360 private HttpSessionContextIntegrationFilter filter;
361 private MockFilterChain chain;
362
363 public ThreadRunner(MockHttpServletRequest request,
364 MockHttpServletResponse response,
365 HttpSessionContextIntegrationFilter filter,
366 MockFilterChain chain) {
367 this.request = request;
368 this.response = response;
369 this.filter = filter;
370 this.chain = chain;
371 }
372
373 public void run() {
374 try {
375
376 executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain);
377
378
379 assertNotNull(request.getSession(false));
380 } catch (Exception e) {
381 e.printStackTrace();
382 }
383 }
384
385 }
386 }