View Javadoc
1   package info.ejava.examples.secureping.ejbclient;
2   
3   
4   import static org.junit.Assert.*;
5   
6   import info.ejava.examples.secureping.ejb.SecurePing;
7   import info.ejava.examples.secureping.ejb.SecurePingRemote;
8   
9   import java.util.Properties;
10  
11  import javax.ejb.EJBAccessException;
12  import javax.naming.Context;
13  import javax.naming.InitialContext;
14  import javax.naming.NamingException;
15  
16  import org.junit.Before;
17  import org.junit.Test;
18  import org.slf4j.Logger;
19  import org.slf4j.LoggerFactory;
20  
21  /**
22   * This class demonstrates accessing the application server and EJB using
23   * JBoss Remoting as different authenticated users. We will perform this
24   * authentication thru the use of the credential properties of the JNDI 
25   * InitialContext.
26   * <pre>
27  java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory                                                                                                              
28  java.naming.factory.url.pkgs=                                                                                                                                      
29  java.naming.provider.url=http-remoting://localhost:8080                                                                                                                                       
30  jboss.naming.client.ejb.context=true  
31  </pre>
32   */
33  public class SecurePingRemotingIT extends SecurePingTestBase {
34      private static final Logger logger = LoggerFactory.getLogger(SecurePingRemotingIT.class);
35      String jndiName = System.getProperty("jndi.name.secureping.remoting",
36              "securePingEAR/securePingEJB/SecurePingEJB!"+SecurePingRemote.class.getName());
37      
38      /**
39       * Sets up the proxy reference to the remote interface of the EJB.
40       */
41      @Before
42      public void setUp() throws Exception {
43      	logger.info("== setUp() ==");
44          logger.debug("jndi name:" + jndiName);
45      }
46      
47      /**
48       * Changes the security context for the connection to the server 
49       * by getting a new InitialContext. Note that the caller must close()
50       * the returned context for future calls to this method to change the 
51       * identity of the caller.
52       * @param username
53       * @param password
54       * @return
55       * @throws NamingException
56       */
57  	private Context runAs(String username, String password) throws NamingException {
58          Properties env = new Properties();
59          if (username != null) {
60  	        env.put(Context.SECURITY_PRINCIPAL, username);
61  	        env.put(Context.SECURITY_CREDENTIALS, password);
62          }
63          env.put("jboss.naming.client.ejb.context", true); //override anything we put there for EJBClient
64          logger.debug(String.format("%s env=%s", username==null?"anonymous":username, env));
65          return new InitialContext(env);
66      }
67      
68      /**
69       * Tests if the server is allowing anonymous users establish an 
70       * InitialContext.
71       * @throws NamingException
72       */
73      @Test 
74      public void testAnonymousInitialContext() throws NamingException {
75      	logger.info("*** testAnonymousInitialContext ***");
76      	try {
77      		Context jndi=runAs(null, null);
78          	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
79          	String response = ejb.pingAll();
80          	if (!response.contains("principal=$local")) {
81          		fail("did not detect anonymous InitialContext");
82      		} else {
83      			logger.debug("JBoss used $local user:" + response);
84      		}
85      	}
86          catch (NamingException ex) {
87              logger.info("expected error for anonymous InitialContext:" + ex);
88          }
89          catch (Exception ex) {
90              logger.error("unexpected exception for anonymous", ex); 
91              fail("unexpected exception for anonymous:" + ex); 
92          }
93      }
94  
95      /**
96       * Logs in as each user type an calls a query method of the EJB that 
97       * will determine if the server side believes we are in the provided
98       * role.
99       * @throws Exception
100      */
101     @Test
102     public void testIsCallerInRole() throws Exception {
103         logger.info("*** testIsCallerInRole ***");
104 
105         Context jndi=null;
106         try {        	
107         	jndi=runAs(null, null);
108         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
109 	        assertFalse("anonomous in admin role", ejb.isCallerInRole("admin"));
110 	        assertFalse("anonomous in user role", ejb.isCallerInRole("user"));
111 	        assertFalse("anonomous in internalRole role", ejb.isCallerInRole("internalRole"));
112 	        jndi.close();
113         }
114         catch (Exception ex) {
115             logger.info("anonymous calls to isCallerinRole failed:"+ex);
116         }
117 
118     	jndi=runAs(knownUser, knownPassword);
119     	SecurePing ejb = (SecurePing)jndi.lookup(jndiName);
120         assertFalse("known in admin role", ejb.isCallerInRole("admin"));
121         assertFalse("known in user role", ejb.isCallerInRole("user"));
122         assertFalse("known in internalRole role", ejb.isCallerInRole("internalRole"));
123 
124     	jndi=runAs(userUser, userPassword);
125     	ejb=(SecurePing)jndi.lookup(jndiName);
126         assertFalse("user in admin role", ejb.isCallerInRole("admin"));
127         assertTrue("user not in user role", ejb.isCallerInRole("user"));
128         assertFalse("user in internalRole role", ejb.isCallerInRole("internalRole"));
129         
130     	jndi=runAs(adminUser, adminPassword);
131     	ejb=(SecurePing)jndi.lookup(jndiName);
132         assertTrue("admin not in admin role", ejb.isCallerInRole("admin"));
133         assertTrue("admin not in user role", ejb.isCallerInRole("user"));
134         assertTrue("user in internalRole role", ejb.isCallerInRole("internalRole"));
135     }
136     
137     /**
138      * Logs in as each use and calls the pingAll() method which permits 
139      * all users to call it. Nobody should get rejected with the exception
140      * of the anonymous user if the server requires an authenticated user 
141      * identity to connect.
142      * @throws Exception
143      */
144     @Test
145     public void testPingAll() throws Exception {
146         logger.info("*** testPingAll ***");
147         Context jndi=null;
148         try {
149         	jndi=runAs(null, null);
150         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
151             String result = ejb.pingAll();
152             logger.info(result);
153             assertEquals("unexpected result for known",
154         		"called pingAll, principal=$local, isUser=false, isAdmin=false, isInternalRole=false",
155         		result);
156         }
157         catch (NamingException ex) {
158             logger.info("expected error calling pingAll:" + ex);
159         }
160         catch (Exception ex) {
161             logger.error("unexpected exception for anonymous", ex); 
162             fail("unexpected exception for anonymous:" + ex); 
163         }
164 
165         try {
166         	jndi = runAs(knownUser, knownPassword);
167         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
168             String result = ejb.pingAll();
169             logger.info(result);
170             assertEquals("unexpected result for known",
171         		"called pingAll, principal=known, isUser=false, isAdmin=false, isInternalRole=false",
172         		result);
173         }
174         catch (Exception ex) {
175             logger.info("error calling pingAll for known", ex);
176             fail("error calling pingAll for known:" +ex);
177         }
178 
179         try {
180         	jndi = runAs(userUser, userPassword);
181         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
182             String result = ejb.pingAll();
183             logger.info(result);
184             assertEquals("unexpected result for admin",
185         		String.format("called pingAll, principal=%s, isUser=true, isAdmin=false, isInternalRole=false", userUser),
186         		result);
187         }
188         catch (Exception ex) {
189             logger.info("error calling pingAll for user", ex);
190             fail("error calling pingAll for user:" +ex);
191         }        
192 
193         try {
194         	jndi = runAs(adminUser, adminPassword);
195         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
196             String result=ejb.pingAll();
197             logger.info(result);
198             assertEquals("unexpected result for admin",
199         		String.format("called pingAll, principal=%s, isUser=true, isAdmin=true, isInternalRole=true", adminUser),
200         		result);
201         }
202         catch (Exception ex) {
203             logger.info("error calling pingAll:" + ex, ex);
204             fail("error calling pingAll:" +ex);
205         }        
206     }
207     
208     /**
209      * Logs in as each user and attempts to invoke a method that requires
210      * the caller to have the user role. This should fail for all but the 
211      * user and admin.
212      * @throws Exception
213      */
214     @Test
215     public void testPingUser() throws Exception {    	
216         logger.info("*** testPingUser ***");
217         Context jndi=null;
218         try {
219         	jndi=runAs(null, null);
220         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
221             logger.info(ejb.pingUser());
222             fail("didn't detect anonymous user");
223         }
224         //depending on how we are invoking this test, we either get denied 
225         //at the JNDI or EJB level -- but at least one will stop us
226         catch (NamingException ex) {
227             logger.info("expected exception thrown:" + ex);
228         }
229         catch (EJBAccessException ex) {
230             logger.info("expected exception thrown:" + ex);
231         }
232         catch (Exception ex) {
233         	fail("unexpected exception type:" + ex);
234         }        
235 
236         try {
237         	jndi=runAs(knownUser, knownPassword);
238         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
239             logger.info(ejb.pingUser());
240             fail("didn't detect known, but non-user");
241         }
242         catch (EJBAccessException ex) {
243             logger.info("expected exception thrown:" + ex);
244         }
245         catch (Exception ex) {
246         	fail("unexpected exception type:" + ex);
247         }        
248         
249         try {
250             jndi = runAs(userUser, userPassword);
251         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
252             logger.info(ejb.pingUser());
253         }
254         catch (Exception ex) {
255             logger.info("error calling pingUser:" + ex, ex);
256             fail("error calling pingUser:" +ex);
257         }        
258 
259         try {
260             jndi = runAs(adminUser, adminPassword);
261         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
262             logger.info(ejb.pingUser());
263         }
264         catch (Exception ex) {
265             logger.info("error calling pingUser:" + ex, ex);
266             fail("error calling pingUser:" +ex);
267         }        
268     }
269 
270     /**
271      * Logs in as each of the users and attempts to invoke a method that
272      * has been restricted to just admins. All but the admin login should
273      * fail.
274      * @throws Exception
275      */
276     @Test
277     public void testPingAdmin() throws Exception {
278         logger.info("*** testPingAdmin ***");
279         Context jndi=null;
280         try {
281         	jndi=runAs(null, null);
282         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
283             logger.info(ejb.pingAdmin());
284             fail("didn't detect anonymous user");
285         }
286         catch (NamingException ex) {
287             logger.info("expected exception thrown:" + ex);
288         }
289         catch (EJBAccessException ex) {
290             logger.info("expected exception thrown:" + ex);
291         }
292         catch (Exception ex) {
293         	fail("unexpected exception type:" + ex);
294         }        
295 
296         try {
297             jndi=runAs(knownUser, knownPassword);
298         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
299             logger.info(ejb.pingAdmin());
300             fail("didn't detect known, but non-admin user");
301         }
302         catch (EJBAccessException ex) {
303             logger.info("expected exception thrown:" + ex);
304         }
305         catch (Exception ex) {
306         	fail("unexpected exception type:" + ex);
307         }        
308         
309         try {
310             jndi = runAs(userUser, userPassword);
311         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
312             logger.info(ejb.pingAdmin());
313             fail("didn't detect non-admin user");
314         }
315         catch (EJBAccessException ex) {
316             logger.info("expected exception thrown:" + ex);
317         }
318         catch (Exception ex) {
319         	fail("unexpected exception type:" + ex);
320         }        
321 
322         try {
323             jndi = runAs(adminUser, adminPassword);
324         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
325             logger.info(ejb.pingAdmin());
326         }
327         catch (Exception ex) {
328             logger.info("error calling pingAdmin:" + ex, ex);
329             fail("error calling pingAdmin:" +ex);
330         }
331     }
332 
333     /**
334      * Logs in as each of the users and attempts to invoke a method that 
335      * has been excluded by all users to call it. All should fail.
336      * @throws Exception
337      */
338     @Test
339     public void testPingExcluded() throws Exception {
340         logger.info("*** testPingExcluded ***");
341         Context jndi=null;
342         try {
343         	jndi=runAs(null, null);
344         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
345             logger.info(ejb.pingExcluded());
346             fail("didn't detect excluded");
347         }
348         catch (NamingException ex) {
349             logger.info("expected exception thrown:" + ex);
350         }
351         catch (EJBAccessException ex) {
352             logger.info("expected exception thrown:" + ex);
353         }
354         catch (Exception ex) {
355         	fail("unexpected exception type:" + ex);
356         }        
357 
358         try {
359             jndi=runAs(knownUser, knownPassword);
360         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
361             logger.info(ejb.pingExcluded());
362             fail("didn't detect excluded");
363         }
364         catch (EJBAccessException ex) {
365             logger.info("expected exception thrown:" + ex);
366         }
367         catch (Exception ex) {
368         	fail("unexpected exception type:" + ex);
369         }        
370         
371         try {
372             jndi = runAs(userUser, userPassword);
373         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
374             logger.info(ejb.pingExcluded());
375             fail("didn't detect excluded");
376         }
377         catch (EJBAccessException ex) {
378             logger.info("expected exception thrown:" + ex);
379         }
380         catch (Exception ex) {
381         	fail("unexpected exception type:" + ex);
382         }        
383 
384         try {
385             jndi = runAs(adminUser, adminPassword);
386         	SecurePing ejb=(SecurePing)jndi.lookup(jndiName);
387             logger.info(ejb.pingExcluded());
388             fail("didn't detect excluded");
389         }
390         catch (EJBAccessException ex) {
391             logger.info("expected exception thrown:" + ex);
392         }
393         catch (Exception ex) {
394         	fail("unexpected exception type:" + ex);
395         }                
396     } 
397 }