1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.richclient.security;
17
18 import junit.framework.TestCase;
19
20 import org.springframework.context.ApplicationEvent;
21 import org.springframework.context.ApplicationListener;
22 import org.springframework.context.support.ClassPathXmlApplicationContext;
23 import org.springframework.richclient.application.Application;
24 import org.springframework.richclient.application.ApplicationServicesLocator;
25 import org.springframework.richclient.application.config.DefaultApplicationLifecycleAdvisor;
26 import org.springframework.richclient.security.support.DefaultApplicationSecurityManager;
27 import org.springframework.security.Authentication;
28 import org.springframework.security.AuthenticationManager;
29 import org.springframework.security.BadCredentialsException;
30 import org.springframework.security.LockedException;
31 import org.springframework.security.SpringSecurityException;
32
33
34
35
36
37
38
39 public class DefaultApplicationSecurityManagerTests extends TestCase {
40
41 private ClassPathXmlApplicationContext ac;
42 private EventCounter eventCounter;
43
44
45
46
47
48 private void prepareApplication(String ctxFileName) {
49 Application.load( null );
50 ApplicationServicesLocator.load(null);
51 Application app = new Application( new DefaultApplicationLifecycleAdvisor() );
52
53 if( ctxFileName != null ) {
54 ac = new ClassPathXmlApplicationContext( "org/springframework/richclient/security/" + ctxFileName );
55 app.setApplicationContext( ac );
56 }
57 }
58
59 public void testConfiguration() {
60 prepareApplication( "security-test-ctx.xml" );
61
62 Object asm = ac.getBean( "applicationSecurityManager" );
63 Object am = ac.getBean( "authenticationManager" );
64
65 assertTrue( "securityManager must implement ApplicationSecurityManager",
66 asm instanceof ApplicationSecurityManager );
67 assertTrue( "securityManager must be instance of DefaultApplicationSecurityManager",
68 asm instanceof DefaultApplicationSecurityManager );
69 assertTrue( "authenticationManager must implement AuthenticationManager", am instanceof AuthenticationManager );
70 assertTrue( "authenticationManager must be instance of TestAuthenticationManager",
71 am instanceof TestAuthenticationManager );
72 assertEquals( asm, ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class) );
73 }
74
75 public void testSecurityEvents() {
76 prepareApplication( "security-test-ctx.xml" );
77 eventCounter = (EventCounter) ac.getBean( "eventCounter" );
78
79 ApplicationSecurityManager asm = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
80 eventCounter.resetCounters();
81 asm.doLogin( TestAuthenticationManager.VALID_USER1 );
82 testCounters( 1, 0, 1, 0 );
83 assertTrue( "User should be logged in now", asm.isUserLoggedIn() );
84 assertEquals( "Authentiation token should be == VALID_USER1", asm.getAuthentication(),
85 TestAuthenticationManager.VALID_USER1 );
86
87
88 doOneFailed( TestAuthenticationManager.BAD_CREDENTIALS, BadCredentialsException.class );
89 doOneFailed( TestAuthenticationManager.LOCKED, LockedException.class );
90
91
92 eventCounter.resetCounters();
93 asm.doLogout();
94 testCounters( 1, 0, 0, 1 );
95 assertNull( "Authentication token should now be null", asm.getAuthentication() );
96 }
97
98 public void testUserInRole() {
99 prepareApplication( "security-test-ctx.xml" );
100 ApplicationSecurityManager asm = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
101 asm.doLogin( TestAuthenticationManager.VALID_USER1 );
102
103 assertTrue( "User should be in role ROLE_EXPECTED", asm.isUserInRole( TestAuthenticationManager.ROLE_EXPECTED ) );
104 assertFalse( "User should not be in role ROLE_UNEXPECTED", asm.isUserInRole( "ROLE_UNEXPECTED" ) );
105 }
106
107 public void testLoginAfterLogin() {
108 prepareApplication( "security-test-ctx.xml" );
109 eventCounter = (EventCounter) ac.getBean( "eventCounter" );
110
111 ApplicationSecurityManager asm = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
112
113 asm.doLogout();
114 asm.doLogin( TestAuthenticationManager.VALID_USER1 );
115
116 eventCounter.resetCounters();
117 asm.doLogin( TestAuthenticationManager.VALID_USER2 );
118
119 testCounters( 1, 0, 1, 0 );
120 assertTrue( "User should be logged in now", asm.isUserLoggedIn() );
121 assertEquals( "Authentiation token should be == VALID_USER2", asm.getAuthentication(),
122 TestAuthenticationManager.VALID_USER2 );
123 }
124
125 public void testAutoConfigurationOnNew() {
126
127
128
129
130 prepareApplication( "security-test-autoconfig-ctx.xml" );
131 ApplicationSecurityManager asm = new DefaultApplicationSecurityManager( true );
132
133
134 Object am = ac.getBean( "authenticationManager" );
135 assertEquals( "Wrong authentication manager configured", am, asm.getAuthenticationManager() );
136 }
137
138 public void testAutoConfigurationFailsWithoutContext() {
139
140 prepareApplication( null );
141 try {
142 ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
143 fail( "Shouldn't be able to auto-configure without context" );
144 } catch( Exception e ) {
145
146 }
147 }
148
149 public void testAutoConfigurationFromServices() {
150
151
152
153 prepareApplication( "security-test-autoconfig-ctx.xml" );
154 ApplicationSecurityManager asm = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
155
156
157 Object am = ac.getBean( "authenticationManager" );
158 assertEquals( "Wrong authentication manager configured", am, asm.getAuthenticationManager() );
159 }
160
161
162
163
164
165
166 private void doOneFailed(Authentication authentication, Class exceptionType) {
167 ApplicationSecurityManager asm = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
168 Authentication current = asm.getAuthentication();
169
170 eventCounter.resetCounters();
171 try {
172 asm.doLogin( authentication );
173 fail( exceptionType.getName() + " should have been thrown" );
174 } catch( SpringSecurityException e ) {
175
176 assertTrue( "Wrong exception thrown; expecting: " + exceptionType.getName(), exceptionType
177 .isAssignableFrom( e.getClass() ) );
178 testCounters( 0, 1, 0, 0 );
179 assertTrue( "User should still be logged in now", asm.isUserLoggedIn() );
180
181 assertEquals( "Authentiation token should not have changed", asm.getAuthentication(), current );
182 }
183 }
184
185
186
187
188 private void testCounters(int authCount, int authFailedCount, int loginCount, int logoutCount) {
189 assertEquals( "AuthenticationEventCount wrong", authCount, eventCounter.authEventCount );
190 assertEquals( "AuthenticationFailedEventCount wrong", authFailedCount, eventCounter.authFailedEventCount );
191 assertEquals( "LoginEventCount wrong", loginCount, eventCounter.loginEventCount );
192 assertEquals( "LogoutEventCount wrong", logoutCount, eventCounter.logoutEventCount );
193 }
194
195
196
197
198 public static class EventCounter implements ApplicationListener {
199 public int authEventCount = 0;
200 public int authFailedEventCount = 0;
201 public int loginEventCount = 0;
202 public int logoutEventCount = 0;
203
204 public EventCounter() {
205 }
206
207 public void onApplicationEvent(ApplicationEvent event) {
208 if( event instanceof AuthenticationEvent ) {
209 authEventCount += 1;
210 } else if( event instanceof AuthenticationFailedEvent ) {
211 authFailedEventCount += 1;
212 } else if( event instanceof LoginEvent ) {
213 loginEventCount += 1;
214 } else if( event instanceof LogoutEvent ) {
215 logoutEventCount += 1;
216 }
217 }
218
219 public void resetCounters() {
220 authEventCount = authFailedEventCount = loginEventCount = logoutEventCount = 0;
221 }
222 }
223 }