View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2005 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.tests.services.security;
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.fail;
21  
22  import java.util.ArrayList;
23  import java.util.Collection;
24  
25  import org.springframework.security.access.AccessDeniedException;
26  import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
27  import org.springframework.security.core.AuthenticationException;
28  import org.springframework.security.core.GrantedAuthority;
29  import org.springframework.security.core.authority.GrantedAuthorityImpl;
30  import org.springframework.security.core.context.SecurityContext;
31  import org.springframework.security.core.context.SecurityContextHolder;
32  import org.springframework.security.core.context.SecurityContextImpl;
33  
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  import org.junit.Test;
37  import org.springframework.context.ApplicationContext;
38  import org.springframework.context.support.ClassPathXmlApplicationContext;
39  
40  import ch.elca.el4j.core.context.ModuleApplicationContext;
41  import ch.elca.el4j.services.security.encryption.RSACipher;
42  import ch.elca.el4j.tests.services.security.provider.ExtendedTestingAuthenticationProvider;
43  import ch.elca.el4j.tests.services.security.sample.SampleService;
44  
45  // Checkstyle: EmptyBlock off
46  // Checkstyle: MagicNumber off
47  
48  /**
49   * Tests various logins and authorization in a local environment.
50   *
51   * @svnLink $Revision: 4091 $;$Date: 2010-01-15 12:21:07 +0100 (Fr, 15. Jan 2010) $;$Author: jonasha $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/security/src/test/java/ch/elca/el4j/tests/services/security/AuthorizationLocalTest.java $
52   *
53   * @author Raphael Boog (RBO)
54   */
55  public class AuthorizationLocalTest {
56  	
57  	/** The static logger. */
58  	private static Logger s_logger = LoggerFactory
59  		.getLogger(AuthorizationLocalTest.class);
60  
61  	/**
62  	 * Method access role.
63  	 */
64  	private static final String METHOD_ACCESS_ROLE = "ROLE_PERMISSION_ADDONE";
65  
66  	/**
67  	 * Config locations.
68  	 */
69  	private String[] m_configLocations = new String[] {
70  		"classpath:optional/security-attributes.xml",
71  		"classpath:scenarios/server/applicationContextTest.xml",
72  		"classpath:scenarios/services/sampleService.xml"};
73  
74  	/**
75  	 * Application context.
76  	 */
77  	private ApplicationContext m_ac;
78  
79  	/**
80  	 * Test tries to execute the target method without authentication.
81  	 *
82  	 * @throws Exception If something.
83  	 */
84  	@Test
85  	public void testMethodCallWithoutLogin() throws Exception {
86  
87  		s_logger.debug("Loading Application Context.");
88  		m_ac = new ModuleApplicationContext(m_configLocations, false);
89  		s_logger.debug("Application Context loaded.");
90  
91  		try {
92  			getSampleService().addOne(1234);
93  			fail("User should not be able to execute this method without "
94  					+ "login");
95  		} catch (AuthenticationCredentialsNotFoundException e) {
96  			// o.k.
97  		} catch (Exception e) {
98  			System.out.println(e);
99  		}
100 
101 	}
102 
103 	/**
104 	 * Test does a correct authorization. Then it does a remote call to the
105 	 * sample service.
106 	 *
107 	 * @throws Exception If something.
108 	 */
109 	@Test
110 	public void testCorrectAuthorization() throws Exception {
111 
112 		s_logger.debug("Loading Application Context.");
113 		m_ac = new ModuleApplicationContext(m_configLocations, false);
114 		s_logger.debug("Application Context loaded.");
115 
116 		createSecureContext("server", "server", METHOD_ACCESS_ROLE);
117 		int result = getSampleService().addOne(1234);
118 		assertEquals(result, 1235);
119 
120 	}
121 
122 	/**
123 	 * Test does a correct authorization. Then it does a remote call to the
124 	 * sample service. Afterwards, it logs out, tries to call the method again
125 	 * and fails.
126 	 *
127 	 * @throws Exception If something.
128 	 */
129 	@Test
130 	public void testCorrectAuthorizationAfterLogoutNoAccess() throws Exception {
131 
132 		s_logger.debug("Loading Application Context.");
133 		m_ac = new ModuleApplicationContext(m_configLocations, false);
134 		s_logger.debug("Application Context loaded.");
135 
136 		createSecureContext("server", "server", METHOD_ACCESS_ROLE);
137 		int result = getSampleService().addOne(1234);
138 		assertEquals(result, 1235);
139 
140 		destroySecureContext();
141 
142 		try {
143 			getSampleService().addOne(1234);
144 			fail("An AccessDeniedException should have been thrown.");
145 		} catch (AuthenticationCredentialsNotFoundException e) {
146 			// ok.
147 		}
148 
149 	}
150 
151 	/**
152 	 * Test does a correct login with the wrong role. Then it does a remote call
153 	 * to the sample service. Since the required permission is not given, the
154 	 * call should throw an exception.
155 	 *
156 	 * @throws Exception If something.
157 	 */
158 	@Test
159 	public void testFailedAuthorization() throws Exception {
160 
161 		s_logger.debug("Loading Application Context.");
162 		m_ac = new ModuleApplicationContext(m_configLocations, false);
163 		s_logger.debug("Application Context loaded.");
164 
165 		createSecureContext("server", "server", "WRONG_ROLE");
166 
167 		try {
168 			getSampleService().addOne(1234);
169 			fail("An AccessDeniedException should have been thrown.");
170 		} catch (AccessDeniedException e) {
171 			// ok.
172 		}
173 	}
174 
175 	/**
176 	 * Test tries to authenticate with a wrong username/password combination. An
177 	 * exception should be thrown.
178 	 *
179 	 * @throws Exception If something.
180 	 */
181 	@Test
182 	public void testFailedAuthentication() throws Exception {
183 
184 		s_logger.debug("Loading Application Context.");
185 		m_ac = new ModuleApplicationContext(m_configLocations, false);
186 		s_logger.debug("Application Context loaded.");
187 
188 		createSecureContext("server", "wrong_credential", "SOME_ROLE");
189 
190 		try {
191 			getSampleService().addOne(1234);
192 			fail("An AuthenticationException should have been thrown.");
193 		} catch (AuthenticationException e) {
194 			// o.k.
195 		}
196 
197 	}
198 
199 	/**
200 	 * Returns the local authentication provider.
201 	 * 
202 	 * @return The ExtendedTestingAuthenticationProvider of this application
203 	 * context.
204 	 */
205 	private ExtendedTestingAuthenticationProvider getAuthenticationProvider() {
206 		
207 		return (ExtendedTestingAuthenticationProvider)
208 			m_ac.getBean("extendedTestingAuthenticationProvider");
209 	}
210 	
211 	/**
212 	 * @return Returns the sample service.
213 	 */
214 	private SampleService getSampleService() {
215 		return (SampleService) m_ac.getBean("sampleService");
216 	}
217 
218 	/**
219 	 * Create a secure context, i.e. login, with a TestingAuthenticationToken,
220 	 * i.e. a token where the user can define which roles it possesses.
221 	 *
222 	 * @param principal
223 	 *            The username
224 	 * @param credential
225 	 *            The password
226 	 * @param role
227 	 *            The role
228 	 */
229 	private void createSecureContext(String principal,
230 		String credential, String role) {
231 		
232 		String publicKey = getAuthenticationProvider().getPublicKey();
233 		RSACipher rsaCipher = new RSACipher(publicKey);
234 		String encryptedCredential = rsaCipher.encrypt(credential);
235 
236 		Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
237 		authorities.add(new GrantedAuthorityImpl("ROLE_TELLER"));
238 		authorities.add(new GrantedAuthorityImpl(role));
239 		
240 		TestingAuthenticationToken auth = new TestingAuthenticationToken(
241 			principal, encryptedCredential, authorities);
242 		SecurityContext sc = SecurityContextHolder.getContext();
243 		sc.setAuthentication(auth);
244 	}
245 
246 	/**
247 	 * Delete the secure context, i.e. logging out the user.
248 	 */
249 	private void destroySecureContext() {
250 		SecurityContextHolder.setContext(new SecurityContextImpl());
251 	}
252 }
253 //Checkstyle: EmptyBlock on
254 //Checkstyle: MagicNumber on