001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.providers.siteminder;
017:
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import junit.framework.TestCase;
022:
023: import org.acegisecurity.AccountExpiredException;
024: import org.acegisecurity.Authentication;
025: import org.acegisecurity.AuthenticationServiceException;
026: import org.acegisecurity.BadCredentialsException;
027: import org.acegisecurity.CredentialsExpiredException;
028: import org.acegisecurity.DisabledException;
029: import org.acegisecurity.GrantedAuthority;
030: import org.acegisecurity.GrantedAuthorityImpl;
031: import org.acegisecurity.LockedException;
032: import org.acegisecurity.providers.TestingAuthenticationToken;
033: import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
034: import org.acegisecurity.providers.dao.UserCache;
035: import org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache;
036: import org.acegisecurity.providers.dao.cache.NullUserCache;
037: import org.acegisecurity.userdetails.User;
038: import org.acegisecurity.userdetails.UserDetails;
039: import org.acegisecurity.userdetails.UserDetailsService;
040: import org.acegisecurity.userdetails.UsernameNotFoundException;
041: import org.springframework.dao.DataAccessException;
042: import org.springframework.dao.DataRetrievalFailureException;
043:
044: /**
045: * Tests {@link SiteminderAuthenticationProvider}.
046: *
047: * @author Ben Alex
048: * @version $Id: SiteminderAuthenticationProviderTests.java 1582 2006-07-15 15:18:51Z smccrory $
049: */
050: public class SiteminderAuthenticationProviderTests extends TestCase {
051: //~ Methods ========================================================================================================
052:
053: public static void main(String[] args) {
054: junit.textui.TestRunner
055: .run(SiteminderAuthenticationProviderTests.class);
056: }
057:
058: public final void setUp() throws Exception {
059: super .setUp();
060: }
061:
062: public void testAuthenticateFailsIfAccountExpired() {
063: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
064: "peter", "opal");
065:
066: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
067: provider
068: .setUserDetailsService(new MockUserDetailsServiceUserPeterAccountExpired());
069: provider.setUserCache(new MockUserCache());
070:
071: try {
072: provider.authenticate(token);
073: fail("Should have thrown AccountExpiredException");
074: } catch (AccountExpiredException expected) {
075: assertTrue(true);
076: }
077: }
078:
079: public void testAuthenticateFailsIfAccountLocked() {
080: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
081: "peter", "opal");
082:
083: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
084: provider
085: .setUserDetailsService(new MockUserDetailsServiceUserPeterAccountLocked());
086: provider.setUserCache(new MockUserCache());
087:
088: try {
089: provider.authenticate(token);
090: fail("Should have thrown LockedException");
091: } catch (LockedException expected) {
092: assertTrue(true);
093: }
094: }
095:
096: public void testAuthenticateFailsIfCredentialsExpired() {
097: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
098: "peter", "opal");
099:
100: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
101: provider
102: .setUserDetailsService(new MockUserDetailsServiceUserPeterCredentialsExpired());
103: provider.setUserCache(new MockUserCache());
104:
105: try {
106: provider.authenticate(token);
107: fail("Should have thrown CredentialsExpiredException");
108: } catch (CredentialsExpiredException expected) {
109: assertTrue(true);
110: }
111:
112: }
113:
114: public void testAuthenticateFailsIfUserDisabled() {
115: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
116: "peter", "opal");
117:
118: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
119: provider
120: .setUserDetailsService(new MockUserDetailsServiceUserPeter());
121: provider.setUserCache(new MockUserCache());
122:
123: try {
124: provider.authenticate(token);
125: fail("Should have thrown DisabledException");
126: } catch (DisabledException expected) {
127: assertTrue(true);
128: }
129: }
130:
131: public void testAuthenticateFailsWhenUserDetailsServiceHasBackendFailure() {
132: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
133: "marissa", "koala");
134:
135: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
136: provider
137: .setUserDetailsService(new MockUserDetailsServiceSimulateBackendError());
138: provider.setUserCache(new MockUserCache());
139:
140: try {
141: provider.authenticate(token);
142: fail("Should have thrown AuthenticationServiceException");
143: } catch (AuthenticationServiceException expected) {
144: assertTrue(true);
145: }
146: }
147:
148: public void testAuthenticateFailsWithEmptyUsername() {
149: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
150: null, "koala");
151:
152: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
153: provider
154: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
155: provider.setUserCache(new MockUserCache());
156:
157: try {
158: provider.authenticate(token);
159: fail("Should have thrown BadCredentialsException");
160: } catch (BadCredentialsException expected) {
161: assertTrue(true);
162: }
163: }
164:
165: public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionFalse() {
166: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
167: "INVALID_USER", "koala");
168:
169: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
170: provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions
171: provider
172: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
173: provider.setUserCache(new MockUserCache());
174:
175: try {
176: provider.authenticate(token);
177: fail("Should have thrown UsernameNotFoundException");
178: } catch (UsernameNotFoundException expected) {
179: assertTrue(true);
180: }
181: }
182:
183: public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionsWithDefaultOfTrue() {
184: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
185: "INVALID_USER", "koala");
186:
187: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
188: assertTrue(provider.isHideUserNotFoundExceptions());
189: provider
190: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
191: provider.setUserCache(new MockUserCache());
192:
193: try {
194: provider.authenticate(token);
195: fail("Should have thrown BadCredentialsException");
196: } catch (BadCredentialsException expected) {
197: assertTrue(true);
198: }
199: }
200:
201: public void testAuthenticateFailsWithMixedCaseUsernameIfDefaultChanged() {
202: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
203: "MaRiSSA", "koala");
204:
205: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
206: provider
207: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
208: provider.setUserCache(new MockUserCache());
209:
210: try {
211: provider.authenticate(token);
212: fail("Should have thrown BadCredentialsException");
213: } catch (BadCredentialsException expected) {
214: assertTrue(true);
215: }
216: }
217:
218: public void testAuthenticates() {
219: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
220: "marissa", "koala");
221: token.setDetails("192.168.0.1");
222:
223: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
224: provider
225: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
226: provider.setUserCache(new MockUserCache());
227:
228: Authentication result = provider.authenticate(token);
229:
230: if (!(result instanceof UsernamePasswordAuthenticationToken)) {
231: fail("Should have returned instance of UsernamePasswordAuthenticationToken");
232: }
233:
234: UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result;
235: assertEquals(User.class, castResult.getPrincipal().getClass());
236: assertEquals("koala", castResult.getCredentials());
237: assertEquals("ROLE_ONE", castResult.getAuthorities()[0]
238: .getAuthority());
239: assertEquals("ROLE_TWO", castResult.getAuthorities()[1]
240: .getAuthority());
241: assertEquals("192.168.0.1", castResult.getDetails());
242: }
243:
244: public void testAuthenticatesASecondTime() {
245: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
246: "marissa", "koala");
247:
248: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
249: provider
250: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
251: provider.setUserCache(new MockUserCache());
252:
253: Authentication result = provider.authenticate(token);
254:
255: if (!(result instanceof UsernamePasswordAuthenticationToken)) {
256: fail("Should have returned instance of UsernamePasswordAuthenticationToken");
257: }
258:
259: // Now try to authenticate with the previous result (with its UserDetails)
260: Authentication result2 = provider.authenticate(result);
261:
262: if (!(result2 instanceof UsernamePasswordAuthenticationToken)) {
263: fail("Should have returned instance of UsernamePasswordAuthenticationToken");
264: }
265:
266: assertEquals(result.getCredentials(), result2.getCredentials());
267: }
268:
269: public void testAuthenticatesWithForcePrincipalAsString() {
270: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
271: "marissa", "koala");
272:
273: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
274: provider
275: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
276: provider.setUserCache(new MockUserCache());
277: provider.setForcePrincipalAsString(true);
278:
279: Authentication result = provider.authenticate(token);
280:
281: if (!(result instanceof UsernamePasswordAuthenticationToken)) {
282: fail("Should have returned instance of UsernamePasswordAuthenticationToken");
283: }
284:
285: UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result;
286: assertEquals(String.class, castResult.getPrincipal().getClass());
287: assertEquals("marissa", castResult.getPrincipal());
288: }
289:
290: public void testDetectsNullBeingReturnedFromUserDetailsService() {
291: UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
292: "marissa", "koala");
293:
294: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
295: provider
296: .setUserDetailsService(new MockUserDetailsServiceReturnsNull());
297:
298: try {
299: provider.authenticate(token);
300: fail("Should have thrown AuthenticationServiceException");
301: } catch (AuthenticationServiceException expected) {
302: assertEquals(
303: "UserDetailsService returned null, which is an interface contract violation",
304: expected.getMessage());
305: }
306: }
307:
308: public void testGettersSetters() {
309: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
310:
311: provider.setUserCache(new EhCacheBasedUserCache());
312: assertEquals(EhCacheBasedUserCache.class, provider
313: .getUserCache().getClass());
314:
315: assertFalse(provider.isForcePrincipalAsString());
316: provider.setForcePrincipalAsString(true);
317: assertTrue(provider.isForcePrincipalAsString());
318: }
319:
320: public void testStartupFailsIfNoUserDetailsService()
321: throws Exception {
322: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
323:
324: try {
325: provider.afterPropertiesSet();
326: fail("Should have thrown IllegalArgumentException");
327: } catch (IllegalArgumentException expected) {
328: assertTrue(true);
329: }
330: }
331:
332: public void testStartupFailsIfNoUserCacheSet() throws Exception {
333: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
334: provider
335: .setUserDetailsService(new MockUserDetailsServiceUserMarissa());
336: assertEquals(NullUserCache.class, provider.getUserCache()
337: .getClass());
338: provider.setUserCache(null);
339:
340: try {
341: provider.afterPropertiesSet();
342: fail("Should have thrown IllegalArgumentException");
343: } catch (IllegalArgumentException expected) {
344: assertTrue(true);
345: }
346: }
347:
348: public void testStartupSuccess() throws Exception {
349: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
350: UserDetailsService userDetailsService = new MockUserDetailsServiceUserMarissa();
351: provider.setUserDetailsService(userDetailsService);
352: provider.setUserCache(new MockUserCache());
353: assertEquals(userDetailsService, provider
354: .getUserDetailsService());
355: provider.afterPropertiesSet();
356: assertTrue(true);
357: }
358:
359: public void testSupports() {
360: SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
361: assertTrue(provider
362: .supports(UsernamePasswordAuthenticationToken.class));
363: assertTrue(!provider.supports(TestingAuthenticationToken.class));
364: }
365:
366: //~ Inner Classes ==================================================================================================
367:
368: private class MockUserDetailsServiceReturnsNull implements
369: UserDetailsService {
370: public UserDetails loadUserByUsername(String username)
371: throws UsernameNotFoundException, DataAccessException {
372: return null;
373: }
374: }
375:
376: private class MockUserDetailsServiceSimulateBackendError implements
377: UserDetailsService {
378: public UserDetails loadUserByUsername(String username)
379: throws UsernameNotFoundException, DataAccessException {
380: throw new DataRetrievalFailureException(
381: "This mock simulator is designed to fail");
382: }
383: }
384:
385: private class MockUserDetailsServiceUserMarissa implements
386: UserDetailsService {
387: private String password = "koala";
388:
389: public UserDetails loadUserByUsername(String username)
390: throws UsernameNotFoundException, DataAccessException {
391: if ("marissa".equals(username)) {
392: return new User("marissa", password, true, true, true,
393: true, new GrantedAuthority[] {
394: new GrantedAuthorityImpl("ROLE_ONE"),
395: new GrantedAuthorityImpl("ROLE_TWO") });
396: } else {
397: throw new UsernameNotFoundException("Could not find: "
398: + username);
399: }
400: }
401:
402: public void setPassword(String password) {
403: this .password = password;
404: }
405: }
406:
407: private class MockUserDetailsServiceUserMarissaWithSalt implements
408: UserDetailsService {
409: public UserDetails loadUserByUsername(String username)
410: throws UsernameNotFoundException, DataAccessException {
411: if ("marissa".equals(username)) {
412: return new User("marissa", "koala{SYSTEM_SALT_VALUE}",
413: true, true, true, true, new GrantedAuthority[] {
414: new GrantedAuthorityImpl("ROLE_ONE"),
415: new GrantedAuthorityImpl("ROLE_TWO") });
416: } else {
417: throw new UsernameNotFoundException("Could not find: "
418: + username);
419: }
420: }
421: }
422:
423: private class MockUserDetailsServiceUserPeter implements
424: UserDetailsService {
425: public UserDetails loadUserByUsername(String username)
426: throws UsernameNotFoundException, DataAccessException {
427: if ("peter".equals(username)) {
428: return new User("peter", "opal", false, true, true,
429: true, new GrantedAuthority[] {
430: new GrantedAuthorityImpl("ROLE_ONE"),
431: new GrantedAuthorityImpl("ROLE_TWO") });
432: } else {
433: throw new UsernameNotFoundException("Could not find: "
434: + username);
435: }
436: }
437: }
438:
439: private class MockUserDetailsServiceUserPeterAccountExpired
440: implements UserDetailsService {
441: public UserDetails loadUserByUsername(String username)
442: throws UsernameNotFoundException, DataAccessException {
443: if ("peter".equals(username)) {
444: return new User("peter", "opal", true, false, true,
445: true, new GrantedAuthority[] {
446: new GrantedAuthorityImpl("ROLE_ONE"),
447: new GrantedAuthorityImpl("ROLE_TWO") });
448: } else {
449: throw new UsernameNotFoundException("Could not find: "
450: + username);
451: }
452: }
453: }
454:
455: private class MockUserDetailsServiceUserPeterAccountLocked
456: implements UserDetailsService {
457: public UserDetails loadUserByUsername(String username)
458: throws UsernameNotFoundException, DataAccessException {
459: if ("peter".equals(username)) {
460: return new User("peter", "opal", true, true, true,
461: false, new GrantedAuthority[] {
462: new GrantedAuthorityImpl("ROLE_ONE"),
463: new GrantedAuthorityImpl("ROLE_TWO") });
464: } else {
465: throw new UsernameNotFoundException("Could not find: "
466: + username);
467: }
468: }
469: }
470:
471: private class MockUserDetailsServiceUserPeterCredentialsExpired
472: implements UserDetailsService {
473: public UserDetails loadUserByUsername(String username)
474: throws UsernameNotFoundException, DataAccessException {
475: if ("peter".equals(username)) {
476: return new User("peter", "opal", true, true, false,
477: true, new GrantedAuthority[] {
478: new GrantedAuthorityImpl("ROLE_ONE"),
479: new GrantedAuthorityImpl("ROLE_TWO") });
480: } else {
481: throw new UsernameNotFoundException("Could not find: "
482: + username);
483: }
484: }
485: }
486:
487: private class MockUserCache implements UserCache {
488: private Map cache = new HashMap();
489:
490: public UserDetails getUserFromCache(String username) {
491: return (User) cache.get(username);
492: }
493:
494: public void putUserInCache(UserDetails user) {
495: cache.put(user.getUsername(), user);
496: }
497:
498: public void removeUserFromCache(String username) {
499: }
500: }
501: }
|