KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > security > test > EJBSpecUnitTestCase


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.test.security.test;
23
24 import java.rmi.RemoteException JavaDoc;
25 import java.rmi.AccessException JavaDoc;
26 import java.rmi.ServerException JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Set JavaDoc;
29 import javax.ejb.Handle JavaDoc;
30 import javax.management.MBeanServerInvocationHandler JavaDoc;
31 import javax.management.MBeanServerConnection JavaDoc;
32 import javax.management.ObjectName JavaDoc;
33 import javax.naming.InitialContext JavaDoc;
34 import javax.rmi.PortableRemoteObject JavaDoc;
35 import javax.jms.Message JavaDoc;
36 import javax.jms.Queue JavaDoc;
37 import javax.jms.QueueConnection JavaDoc;
38 import javax.jms.QueueConnectionFactory JavaDoc;
39 import javax.jms.QueueReceiver JavaDoc;
40 import javax.jms.QueueSender JavaDoc;
41 import javax.jms.QueueSession JavaDoc;
42 import javax.jms.Session JavaDoc;
43 import javax.security.auth.login.Configuration JavaDoc;
44 import javax.security.auth.login.LoginContext JavaDoc;
45
46 import org.jboss.security.auth.login.XMLLoginConfigImpl;
47 import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
48 import org.jboss.security.SimplePrincipal;
49 import org.jboss.test.JBossTestCase;
50 import org.jboss.test.JBossTestSetup;
51 import org.jboss.test.security.interfaces.CalledSession;
52 import org.jboss.test.security.interfaces.CalledSessionHome;
53 import org.jboss.test.security.interfaces.StatefulSession;
54 import org.jboss.test.security.interfaces.StatefulSessionHome;
55 import org.jboss.test.security.interfaces.StatelessSession;
56 import org.jboss.test.security.interfaces.StatelessSessionHome;
57 import org.jboss.test.security.interfaces.SecurityContext;
58 import org.jboss.test.security.interfaces.SecurityContextHome;
59 import org.jboss.test.security.ejb.jbas1852.SessionFacade;
60 import org.jboss.test.security.ejb.jbas1852.SessionFacadeHome;
61 import org.jboss.test.util.AppCallbackHandler;
62 import org.jboss.logging.Logger;
63
64 import junit.extensions.TestSetup;
65 import junit.framework.Test;
66 import junit.framework.TestSuite;
67
68
69 /** Test of EJB spec conformace using the security-spec.jar
70  deployment unit. These test the basic role based access model.
71  
72  @author Scott.Stark@jboss.org
73  @version $Revision: 58115 $
74  */

75 public class EJBSpecUnitTestCase
76    extends JBossTestCase
77 {
78    static String JavaDoc username = "scott";
79    static char[] password = "echoman".toCharArray();
80    static String JavaDoc QUEUE_FACTORY = "ConnectionFactory";
81    
82    LoginContext JavaDoc lc;
83    boolean loggedIn;
84
85    public EJBSpecUnitTestCase(String JavaDoc name)
86    {
87       super(name);
88    }
89
90    /** Validate that the users have the expected logins and roles.
91     *
92     * @throws Exception
93     */

94    public void testSecurityDomain() throws Exception JavaDoc
95    {
96       log.info("+++ testSecurityDomain, domain=spec-test");
97       MBeanServerConnection JavaDoc conn = (MBeanServerConnection JavaDoc) getServer();
98       ObjectName JavaDoc secMgrName = new ObjectName JavaDoc("jboss.security:service=JaasSecurityManager");
99       JaasSecurityManagerServiceMBean secMgr = (JaasSecurityManagerServiceMBean)
100          MBeanServerInvocationHandler.newProxyInstance(conn, secMgrName,
101          JaasSecurityManagerServiceMBean.class, false);
102
103       // Test the spec-test security domain
104
String JavaDoc domain = "spec-test";
105       SimplePrincipal user = new SimplePrincipal("scott");
106       boolean isValid = secMgr.isValid(domain, user, password);
107       assertTrue("scott password is echoman", isValid);
108       HashSet JavaDoc testRole = new HashSet JavaDoc();
109       testRole.add(new SimplePrincipal("Echo"));
110       boolean hasRole = secMgr.doesUserHaveRole(domain, user, password, testRole);
111       assertTrue("scott has Echo role", hasRole);
112       testRole.clear();
113       testRole.add(new SimplePrincipal("EchoLocal"));
114       hasRole = secMgr.doesUserHaveRole(domain, user, password, testRole);
115       assertTrue("scott has EchoLocal role", hasRole);
116       testRole.clear();
117       testRole.add(new SimplePrincipal("ProjectUser"));
118       hasRole = secMgr.doesUserHaveRole(domain, user, password, testRole);
119       assertTrue("scott has ProjectUser role", hasRole);
120
121       isValid = secMgr.isValid(domain, user, "badpass".toCharArray());
122       assertTrue("badpass is an invalid password for scott", isValid == false);
123
124       // Test the spec-test-domain security domain
125
log.info("+++ testSecurityDomain, domain=spec-test-domain");
126       domain = "spec-test-domain";
127       isValid = secMgr.isValid(domain, user, password);
128       assertTrue("scott password is echoman", isValid);
129       hasRole = secMgr.doesUserHaveRole(domain, user, password, testRole);
130       assertTrue("scott has Echo role", hasRole);
131       testRole.clear();
132       SimplePrincipal echoLocal = new SimplePrincipal("EchoLocal");
133       testRole.add(echoLocal);
134       hasRole = secMgr.doesUserHaveRole(domain, user, password, testRole);
135       assertTrue("scott has EchoLocal role", hasRole);
136       testRole.clear();
137       SimplePrincipal projectUser = new SimplePrincipal("ProjectUser");
138       testRole.add(projectUser);
139       hasRole = secMgr.doesUserHaveRole(domain, user, password, testRole);
140       assertTrue("scott has ProjectUser role", hasRole);
141       Set JavaDoc roles = secMgr.getUserRoles(domain, user, password);
142       assertTrue(roles != null);
143       assertTrue("roles contains EchoLocal", roles.contains(echoLocal));
144       assertTrue("roles contains ProjectUser", roles.contains(projectUser));
145
146       isValid = secMgr.isValid(domain, user, "badpass".toCharArray());
147       assertTrue("badpass is an invalid password for scott", isValid == false);
148    }
149
150    /** Test the use of getCallerPrincipal from within the ejbCreate
151     * in a stateful session bean
152     */

153    public void testStatefulCreateCaller() throws Exception JavaDoc
154    {
155       log.debug("+++ testStatefulCreateCaller");
156       login();
157       InitialContext JavaDoc jndiContext = new InitialContext JavaDoc();
158       Object JavaDoc obj = jndiContext.lookup("spec.StatefulSession");
159       obj = PortableRemoteObject.narrow(obj, StatefulSessionHome.class);
160       StatefulSessionHome home = (StatefulSessionHome) obj;
161       log.debug("Found StatefulSessionHome");
162       // The create should be allowed to call getCallerPrincipal
163
StatefulSession bean = home.create("testStatefulCreateCaller");
164       // Need to invoke a method to ensure an ejbCreate call
165
bean.echo("testStatefulCreateCaller");
166       log.debug("Bean.echo(), ok");
167
168       logout();
169    }
170
171    /** Test that:
172     1. SecureBean returns a non-null principal when getCallerPrincipal
173     is called with a security context and that this is propagated
174     to its Entity bean ref.
175     
176     2. UnsecureBean throws an IllegalStateException when getCallerPrincipal
177     is called without a security context.
178     */

179    public void testGetCallerPrincipal() throws Exception JavaDoc
180    {
181       logout();
182       log.debug("+++ testGetCallerPrincipal()");
183       Object JavaDoc obj = getInitialContext().lookup("spec.UnsecureStatelessSession2");
184       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
185       StatelessSessionHome home = (StatelessSessionHome) obj;
186       log.debug("Found Unsecure StatelessSessionHome");
187       StatelessSession bean = home.create();
188       log.debug("Created spec.UnsecureStatelessSession2");
189       
190       try
191       {
192          // This should fail because echo calls getCallerPrincipal()
193
bean.echo("Hello from nobody?");
194          fail("Was able to call StatelessSession.echo");
195       }
196       catch(RemoteException JavaDoc e)
197       {
198          log.debug("echo failed as expected");
199       }
200       bean.remove();
201       
202       login();
203       obj = getInitialContext().lookup("spec.StatelessSession2");
204       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
205       home = (StatelessSessionHome) obj;
206       log.debug("Found spec.StatelessSession2");
207       bean = home.create();
208       log.debug("Created spec.StatelessSession2");
209       // Test that the Entity bean sees username as its principal
210
String JavaDoc echo = bean.echo(username);
211       log.debug("bean.echo(username) = "+echo);
212       assertTrue("username == echo", echo.equals(username));
213       bean.remove();
214    }
215
216    /**
217     * Test that a call interacting with different security domains does not
218     * change the
219     * @throws Exception
220     */

221    public void testDomainInteraction() throws Exception JavaDoc
222    {
223       logout();
224       login("testDomainInteraction", "testDomainInteraction".toCharArray());
225       log.debug("+++ testDomainInteraction()");
226       Object JavaDoc obj = getInitialContext().lookup("spec.UserInRoleContextSession");
227       obj = PortableRemoteObject.narrow(obj, SecurityContextHome.class);
228       SecurityContextHome home = (SecurityContextHome) obj;
229       log.debug("Found UserInRoleContextSession");
230       SecurityContext bean = home.create();
231       log.debug("Created spec.UserInRoleContextSession");
232       HashSet JavaDoc roles = new HashSet JavaDoc();
233       roles.add("Role1");
234       roles.add("Role2");
235       bean.testDomainInteraction(roles);
236       bean.remove();
237    }
238
239    /** Test that the calling principal is propagated across bean calls.
240     */

241    public void testPrincipalPropagation() throws Exception JavaDoc
242    {
243       log.debug("+++ testPrincipalPropagation");
244       logout();
245       login();
246       Object JavaDoc obj = getInitialContext().lookup("spec.UnsecureStatelessSession2");
247       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
248       StatelessSessionHome home = (StatelessSessionHome) obj;
249       log.debug("Found Unsecure StatelessSessionHome");
250       StatelessSession bean = home.create();
251       log.debug("Created spec.UnsecureStatelessSession2");
252       log.debug("Bean.forward('testPrincipalPropagation') -> "+bean.forward("testPrincipalPropagation"));
253       bean.remove();
254    }
255    
256    /** Test that the echo method is accessible by an Echo
257     role. Since the noop() method of the StatelessSession
258     bean was not assigned any permissions it should be unchecked.
259     */

260    public void testMethodAccess() throws Exception JavaDoc
261    {
262       log.debug("+++ testMethodAccess");
263       login();
264       Object JavaDoc obj = getInitialContext().lookup("spec.StatelessSession");
265       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
266       StatelessSessionHome home = (StatelessSessionHome) obj;
267       log.debug("Found StatelessSessionHome");
268       StatelessSession bean = home.create();
269       log.debug("Created spec.StatelessSession");
270       log.debug("Bean.echo('Hello') -> "+bean.echo("Hello"));
271
272       try
273       {
274          // This should not be allowed
275
bean.noop();
276          fail("Was able to call StatelessSession.noop");
277       }
278       catch(RemoteException JavaDoc e)
279       {
280          log.debug("StatelessSession.noop failed as expected");
281       }
282       bean.remove();
283    }
284
285    /** Test that the echo method is accessible by an Echo
286     role. Since the excluded() method of the StatelessSession
287     bean has been placed into the excluded set it should not
288     accessible by any user. This uses the security domain of the
289     JaasSecurityDomain service to test its use as an authentication mgr.
290     */

291    public void testDomainMethodAccess() throws Exception JavaDoc
292    {
293       log.debug("+++ testDomainMethodAccess");
294       login();
295       Object JavaDoc obj = getInitialContext().lookup("spec.StatelessSessionInDomain");
296       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
297       StatelessSessionHome home = (StatelessSessionHome) obj;
298       log.debug("Found StatelessSessionInDomain home");
299       StatelessSession bean = home.create();
300       log.debug("Created spec.StatelessSessionInDomain");
301       log.debug("Bean.echo('testDomainMethodAccess') -> "+bean.echo("testDomainMethodAccess"));
302
303       try
304       {
305          // This should not be allowed
306
bean.excluded();
307          fail("Was able to call StatelessSession.excluded");
308       }
309       catch(RemoteException JavaDoc e)
310       {
311          log.debug("StatelessSession.excluded failed as expected");
312       }
313       bean.remove();
314    }
315
316    /** Test that the permissions assigned to the stateless session bean:
317     with ejb-name=org/jboss/test/security/ejb/StatelessSession_test
318     are read correctly.
319     */

320    public void testMethodAccess2() throws Exception JavaDoc
321    {
322       log.debug("+++ testMethodAccess2");
323       login();
324       InitialContext JavaDoc jndiContext = new InitialContext JavaDoc();
325       Object JavaDoc obj = jndiContext.lookup("spec.StatelessSession_test");
326       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
327       StatelessSessionHome home = (StatelessSessionHome) obj;
328       log.debug("Found StatelessSessionHome");
329       StatelessSession bean = home.create();
330       log.debug("Created spec.StatelessSession_test");
331       log.debug("Bean.echo('testMethodAccess2') -> "+bean.echo("testMethodAccess2"));
332       bean.remove();
333    }
334
335    /** Test a user with Echo and EchoLocal roles can access the CalleeBean
336     through its local interface by calling the CallerBean and that a user
337     with only a EchoLocal cannot call the CallerBean.
338     */

339    public void testLocalMethodAccess() throws Exception JavaDoc
340    {
341       log.debug("+++ testLocalMethodAccess");
342       login();
343       InitialContext JavaDoc jndiContext = new InitialContext JavaDoc();
344       Object JavaDoc obj = jndiContext.lookup("spec.CallerBean");
345       obj = PortableRemoteObject.narrow(obj, CalledSessionHome.class);
346       CalledSessionHome home = (CalledSessionHome) obj;
347       log.debug("Found spec.CallerBean Home");
348       CalledSession bean = home.create();
349       log.debug("Created spec.CallerBean");
350       log.debug("Bean.invokeEcho('testLocalMethodAccess') -> "+bean.invokeEcho("testLocalMethodAccess"));
351       bean.remove();
352    }
353
354    /** Test access to a bean with a mix of remote interface permissions and
355     * unchecked permissions with the unchecked permissions declared first.
356     * @throws Exception
357     */

358    public void testUncheckedRemote() throws Exception JavaDoc
359    {
360       log.debug("+++ testUncheckedRemote");
361       login();
362       Object JavaDoc obj = getInitialContext().lookup("spec.UncheckedSessionRemoteLast");
363       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
364       StatelessSessionHome home = (StatelessSessionHome) obj;
365       log.debug("Found UncheckedSessionRemoteLast");
366       StatelessSession bean = home.create();
367       log.debug("Created spec.UncheckedSessionRemoteLast");
368       log.debug("Bean.echo('testUncheckedRemote') -> "+bean.echo("testUncheckedRemote"));
369       try
370       {
371          bean.excluded();
372          fail("Was able to call UncheckedSessionRemoteLast.excluded");
373       }
374       catch(RemoteException JavaDoc e)
375       {
376          log.debug("UncheckedSessionRemoteLast.excluded failed as expected");
377       }
378       bean.remove();
379       logout();
380    }
381
382    /** Test access to a bean with a mix of remote interface permissions and
383     * unchecked permissions with the unchecked permissions declared last.
384     * @throws Exception
385     */

386    public void testRemoteUnchecked() throws Exception JavaDoc
387    {
388       log.debug("+++ testRemoteUnchecked");
389       login();
390       Object JavaDoc obj = getInitialContext().lookup("spec.UncheckedSessionRemoteFirst");
391       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
392       StatelessSessionHome home = (StatelessSessionHome) obj;
393       log.debug("Found UncheckedSessionRemoteFirst");
394       StatelessSession bean = home.create();
395       log.debug("Created spec.UncheckedSessionRemoteFirst");
396       log.debug("Bean.echo('testRemoteUnchecked') -> "+bean.echo("testRemoteUnchecked"));
397       try
398       {
399          bean.excluded();
400          fail("Was able to call UncheckedSessionRemoteFirst.excluded");
401       }
402       catch(RemoteException JavaDoc e)
403       {
404          log.debug("UncheckedSessionRemoteFirst.excluded failed as expected");
405       }
406       bean.remove();
407       logout();
408    }
409
410    /** Test that a user with a role that has not been assigned any
411     method permissions in the ejb-jar descriptor is able to access a
412     method that has been marked as unchecked.
413     */

414    public void testUnchecked() throws Exception JavaDoc
415    {
416       log.debug("+++ testUnchecked");
417       // Login as scott to create the bean
418
login();
419       Object JavaDoc obj = getInitialContext().lookup("spec.StatelessSession");
420       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
421       StatelessSessionHome home = (StatelessSessionHome) obj;
422       log.debug("Found spec.StatelessSession Home");
423       StatelessSession bean = home.create();
424       log.debug("Created spec.StatelessSession");
425       // Logout and login back in as stark to test access to the unchecked method
426
logout();
427       login("stark", "javaman".toCharArray());
428       bean.unchecked();
429       log.debug("Called Bean.unchecked()");
430       logout();
431    }
432
433    /** Test that a user with a valid role is able to access a
434     bean for which all methods have been marked as unchecked.
435     */

436    public void testUncheckedWithLogin() throws Exception JavaDoc
437    {
438       log.debug("+++ testUncheckedWithLogin");
439       // Login as scott to see that a user with roles is allowed access
440
login();
441       Object JavaDoc obj = getInitialContext().lookup("spec.UncheckedSession");
442       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
443       StatelessSessionHome home = (StatelessSessionHome) obj;
444       log.debug("Found spec.StatelessSession Home");
445       StatelessSession bean = home.create();
446       log.debug("Created spec.StatelessSession");
447       bean.unchecked();
448       log.debug("Called Bean.unchecked()");
449       logout();
450    }
451
452    /** Test that user scott who has the Echo role is not able to
453     access the StatelessSession2.excluded method even though
454     the Echo role has been granted access to all methods of
455     StatelessSession2 to test that the excluded-list takes
456     precendence over the method-permissions.
457     */

458    public void testExcluded() throws Exception JavaDoc
459    {
460       log.debug("+++ testExcluded");
461       login();
462       Object JavaDoc obj = getInitialContext().lookup("spec.StatelessSession2");
463       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
464       StatelessSessionHome home = (StatelessSessionHome) obj;
465       log.debug("Found spec.StatelessSession2 Home");
466       StatelessSession bean = home.create();
467       log.debug("Created spec.StatelessSession2");
468       try
469       {
470          bean.excluded();
471          fail("Was able to call Bean.excluded()");
472       }
473       catch(Exception JavaDoc e)
474       {
475          log.debug("Bean.excluded() failed as expected");
476          // This is what we expect
477
}
478       logout();
479    }
480    
481    /** This method tests the following call chains:
482     1. RunAsStatelessSession.echo() -> PrivateEntity.echo()
483     2. RunAsStatelessSession.noop() -> RunAsStatelessSession.excluded()
484     3. RunAsStatelessSession.forward() -> StatelessSession.echo()
485     1. Should succeed because the run-as identity of RunAsStatelessSession
486     is valid for accessing PrivateEntity.
487     2. Should succeed because the run-as identity of RunAsStatelessSession
488     is valid for accessing RunAsStatelessSession.excluded().
489     3. Should fail because the run-as identity of RunAsStatelessSession
490     is not Echo.
491     */

492    public void testRunAs() throws Exception JavaDoc
493    {
494       log.debug("+++ testRunAs");
495       login();
496       Object JavaDoc obj = getInitialContext().lookup("spec.RunAsStatelessSession");
497       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
498       StatelessSessionHome home = (StatelessSessionHome) obj;
499       log.debug("Found RunAsStatelessSession Home");
500       StatelessSession bean = home.create();
501       log.debug("Created spec.RunAsStatelessSession");
502       log.debug("Bean.echo('testRunAs') -> "+bean.echo("testRunAs"));
503       bean.noop();
504       log.debug("Bean.noop(), ok");
505       
506       try
507       {
508          // This should not be allowed
509
bean.forward("Hello");
510          fail("Was able to call RunAsStatelessSession.forward");
511       }
512       catch(RemoteException JavaDoc e)
513       {
514          log.debug("StatelessSession.forward failed as expected");
515       }
516       bean.remove();
517    }
518
519    /** This method tests the following call chain:
520     Level1CallerBean.callEcho() -> Level2CallerBean.invokeEcho()
521       -> Level3CalleeBean.echo()
522     The Level1CallerBean uses a run-as of InternalRole and the Level2CallerBean
523     and Level3CalleeBean are only accessible by InternalRole.
524     */

525    public void testDeepRunAs() throws Exception JavaDoc
526    {
527       log.debug("+++ testDeepRunAs");
528       login();
529       Object JavaDoc obj = getInitialContext().lookup("spec.Level1CallerBean");
530       obj = PortableRemoteObject.narrow(obj, CalledSessionHome.class);
531       CalledSessionHome home = (CalledSessionHome) obj;
532       log.debug("Found Level1CallerBean Home");
533       CalledSession bean = home.create();
534       log.debug("Created spec.Level1CallerBean");
535       bean.callEcho();
536       log.debug("Bean.callEcho() ok");
537       bean.remove();
538
539       // Make sure we cannot access Level2CallerBean remotely
540
obj = getInitialContext().lookup("spec.Level2CallerBean");
541       obj = PortableRemoteObject.narrow(obj, CalledSessionHome.class);
542       home = (CalledSessionHome) obj;
543       log.debug("Found Level2CallerBean Home");
544       try
545       {
546          bean = home.create();
547          fail("Was able to create Level2CallerBean");
548       }
549       catch(ServerException JavaDoc e)
550       {
551          AccessException JavaDoc ae = (AccessException JavaDoc) e.detail;
552          log.debug("Caught AccessException as expected", ae);
553       }
554       catch(AccessException JavaDoc e)
555       {
556          log.debug("Caught AccessException as expected", e);
557       }
558    }
559
560    public void testRunAsSFSB() throws Exception JavaDoc
561    {
562       log.info("+++ testRunAsSFSB");
563       login();
564       Object JavaDoc obj = getInitialContext().lookup("spec.CallerFacadeBean-testRunAsSFSB");
565       obj = PortableRemoteObject.narrow(obj, CalledSessionHome.class);
566       CalledSessionHome home = (CalledSessionHome) obj;
567       log.debug("Found CallerFacadeBean-testRunAsSFSB Home");
568       CalledSession bean = home.create();
569       log.debug("Created spec.CallerFacadeBean-testRunAsSFSB");
570       bean.invokeEcho("testRunAsSFSB");
571       log.debug("Bean.invokeEcho() ok");
572       bean.remove();
573    }
574
575    /**
576     * Test the run-as side-effects raised in
577     * http://jira.jboss.com/jira/browse/JBAS-1852
578     *
579     * @throws Exception
580     */

581    public void testJBAS1852() throws Exception JavaDoc
582    {
583       log.info("+++ testJBAS1852");
584       login();
585       Object JavaDoc obj = getInitialContext().lookup("spec.PublicSessionFacade");
586       obj = PortableRemoteObject.narrow(obj, SessionFacadeHome.class);
587       SessionFacadeHome home = (SessionFacadeHome) obj;
588       log.debug("Found PublicSessionFacade home");
589       SessionFacade bean = home.create();
590       log.debug("Created PublicSessionFacade");
591       log.debug("Bean.callEcho('testJBAS1852') -> " + bean.callEcho("testJBAS1852"));
592       bean.remove();
593    }
594
595    /** Test that an MDB with a run-as identity is able to access secure EJBs
596     that require the identity.
597     */

598    public void testMDBRunAs() throws Exception JavaDoc
599    {
600       log.debug("+++ testMDBRunAs");
601       logout();
602       QueueConnectionFactory JavaDoc queueFactory = (QueueConnectionFactory JavaDoc) getInitialContext().lookup(QUEUE_FACTORY);
603       Queue JavaDoc queA = (Queue JavaDoc) getInitialContext().lookup("queue/QueueA");
604       Queue JavaDoc queB = (Queue JavaDoc) getInitialContext().lookup("queue/QueueB");
605       QueueConnection JavaDoc queueConn = queueFactory.createQueueConnection();
606       QueueSession JavaDoc session = queueConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
607       Message JavaDoc msg = session.createMessage();
608       msg.setStringProperty("arg", "testMDBRunAs");
609       msg.setJMSReplyTo(queB);
610       QueueSender JavaDoc sender = session.createSender(queA);
611       sender.send(msg);
612       sender.close();
613       log.debug("Sent msg to queue/QueueA");
614       queueConn.start();
615       QueueReceiver JavaDoc recv = session.createReceiver(queB);
616       msg = recv.receive(5000);
617       log.debug("Recv msg: "+msg);
618       String JavaDoc info = msg.getStringProperty("reply");
619       recv.close();
620       session.close();
621       queueConn.close();
622
623       if( info == null || info.startsWith("Failed") )
624       {
625          fail("Recevied exception reply, info="+info);
626       }
627    }
628
629    /** Test that an MDB with a run-as identity is able to access secure EJBs
630     that require the identity. DeepRunAsMDB -> Level1MDBCallerBean.callEcho() ->
631       Level2CallerBean.invokeEcho() -> Level3CalleeBean.echo()
632     The MDB uses a run-as of InternalRole and the Level2CallerBean
633     and Level3CalleeBean are only accessible by InternalRole.
634     */

635    public void testMDBDeepRunAs() throws Exception JavaDoc
636    {
637       log.debug("+++ testMDBDeepRunAs");
638       logout();
639       QueueConnectionFactory JavaDoc queueFactory = (QueueConnectionFactory JavaDoc) getInitialContext().lookup(QUEUE_FACTORY);
640       Queue JavaDoc queD = (Queue JavaDoc) getInitialContext().lookup("queue/QueueD");
641       Queue JavaDoc queB = (Queue JavaDoc) getInitialContext().lookup("queue/QueueB");
642       QueueConnection JavaDoc queueConn = queueFactory.createQueueConnection();
643       QueueSession JavaDoc session = queueConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
644       Message JavaDoc msg = session.createMessage();
645       msg.setStringProperty("arg", "testMDBDeepRunAs");
646       msg.setJMSReplyTo(queB);
647       QueueSender JavaDoc sender = session.createSender(queD);
648       sender.send(msg);
649       sender.close();
650       log.debug("Sent msg to "+queD);
651       queueConn.start();
652       QueueReceiver JavaDoc recv = session.createReceiver(queB);
653       msg = recv.receive(5000);
654       log.debug("Recv msg: "+msg);
655       String JavaDoc info = msg.getStringProperty("reply");
656       recv.close();
657       session.close();
658       queueConn.close();
659
660       if( info == null || info.startsWith("Failed") )
661       {
662          fail("Recevied exception reply, info="+info);
663       }
664    }
665
666    /** This method tests that the RunAsWithRolesMDB is assigned multiple roles
667     * within its onMessage so that it can call into the ProjRepository session
668     * bean's methods that required ProjectAdmin, CreateFolder and DeleteFolder
669     * roles.
670     */

671    public void testRunAsWithRoles() throws Exception JavaDoc
672    {
673       log.debug("+++ testRunAsWithRoles");
674       logout();
675       QueueConnectionFactory JavaDoc queueFactory = (QueueConnectionFactory JavaDoc) getInitialContext().lookup(QUEUE_FACTORY);
676       Queue JavaDoc queC = (Queue JavaDoc) getInitialContext().lookup("queue/QueueC");
677       Queue JavaDoc queB = (Queue JavaDoc) getInitialContext().lookup("queue/QueueB");
678       QueueConnection JavaDoc queueConn = queueFactory.createQueueConnection();
679       QueueSession JavaDoc session = queueConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
680       Message JavaDoc msg = session.createMessage();
681       msg.setStringProperty("name", "testRunAsWithRoles");
682       msg.setJMSReplyTo(queB);
683       QueueSender JavaDoc sender = session.createSender(queC);
684       sender.send(msg);
685       sender.close();
686       log.debug("Sent msg to queue/QueueC");
687       queueConn.start();
688       QueueReceiver JavaDoc recv = session.createReceiver(queB);
689       msg = recv.receive(5000);
690       log.debug("Recv msg: "+msg);
691       String JavaDoc info = msg.getStringProperty("reply");
692       recv.close();
693       session.close();
694       queueConn.close();
695
696       if( info == null || info.startsWith("Failed") )
697       {
698          fail("Recevied exception reply, info="+info);
699       }
700    }
701
702    /** Test the security behavior of handles. To obtain secured bean from
703       a handle that the handle be
704     */

705    public void testHandle() throws Exception JavaDoc
706    {
707       log.debug("+++ testHandle");
708       login();
709       Object JavaDoc obj = getInitialContext().lookup("spec.StatelessSession");
710       obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
711       StatelessSessionHome home = (StatelessSessionHome) obj;
712       log.debug("Found StatelessSessionHome");
713       StatelessSession bean = home.create();
714       log.debug("Created spec.StatelessSession");
715       Handle JavaDoc h = bean.getHandle();
716       log.debug("Obtained handle: "+h);
717       bean = (StatelessSession) h.getEJBObject();
718       log.debug("Obtained bean from handle: "+bean);
719       log.debug("Bean.echo('testHandle') -> "+bean.echo("testHandle"));
720       logout();
721
722       /* Attempting to obtain the EJB fron the handle without security
723        association present should fail
724       */

725       try
726       {
727          bean = (StatelessSession) h.getEJBObject();
728          fail("Should not be able to obtain a bean without login info");
729       }
730       catch(Exception JavaDoc e)
731       {
732          log.debug("Obtaining bean from handle failed as expected, e="+e.getMessage());
733       }
734
735       // One should be able to obtain a handle without a login
736
h = bean.getHandle();
737       login();
738       // Now we should be able to obtain and use the secure bean
739
bean = (StatelessSession) h.getEJBObject();
740       log.debug("Obtained bean from handle: "+bean);
741       log.debug("Bean.echo('testHandle2') -> "+bean.echo("testHandle2"));
742       logout();
743    }
744
745    /** Test the security behavior of stateful handles. To obtain secured bean
746     from a handle requires that there be a security context to obtain the ejb.
747     */

748    public void testStatefulHandle() throws Exception JavaDoc
749    {
750       log.debug("+++ testStatefulHandle");
751       login();
752       Object JavaDoc obj = getInitialContext().lookup("spec.StatefulSession");
753       obj = PortableRemoteObject.narrow(obj, StatefulSessionHome.class);
754       StatefulSessionHome home = (StatefulSessionHome) obj;
755       log.debug("Found StatefulSession");
756       StatefulSession bean = home.create("testStatefulHandle");
757       log.debug("Created spec.StatelessSession");
758       Handle JavaDoc h = bean.getHandle();
759       log.debug("Obtained handle: "+h);
760       bean = (StatefulSession) h.getEJBObject();
761       log.debug("Obtained bean from handle: "+bean);
762       log.debug("Bean.echo('Hello') -> "+bean.echo("Hello"));
763       logout();
764
765       /* Attempting to obtain the EJB fron the handle without security
766        association present should fail
767       */

768       try
769       {
770          bean = (StatefulSession) h.getEJBObject();
771          fail("Should not be able to obtain a bean without login info");
772       }
773       catch(Exception JavaDoc e)
774       {
775          log.debug("Obtaining bean from handle failed as expected, e="+e.getMessage());
776       }
777
778       // One should be able to obtain a handle without a login
779
h = bean.getHandle();
780       login();
781       // Now we should be able to obtain and use the secure bean
782
bean = (StatefulSession) h.getEJBObject();
783       log.debug("Obtained bean from handle: "+bean);
784       log.debug("Bean.echo('Hello') -> "+bean.echo("Hello"));
785       logout();
786    }
787
788    /** Stress test declarative security.
789     */

790    public void testStress() throws Exception JavaDoc
791    {
792       log.debug("+++ testStress");
793       int count = Integer.getInteger("jbosstest.threadcount", 10).intValue();
794       int iterations = Integer.getInteger("jbosstest.iterationcount", 5000).intValue();
795       // Use a minimum of 100 iterations
796
if( iterations < 100 )
797          iterations = 100;
798       log.info("Creating "+count+" threads doing "+iterations+" iterations");
799       Thread JavaDoc[] testThreads = new Thread JavaDoc[count];
800       StressTester[] testers = new StressTester[count];
801       
802       for(int t = 0; t < count; t ++)
803       {
804          StressTester test = new StressTester(getInitialContext(), iterations);
805          testers[t] = test;
806          Thread JavaDoc thr = new Thread JavaDoc(test, "Tester#"+t);
807          thr.start();
808          testThreads[t] = thr;
809       }
810
811       int errorCount = 0;
812       for(int t = 0; t < count; t ++)
813       {
814          Thread JavaDoc thr = testThreads[t];
815          thr.join();
816          StressTester test = testers[t];
817          if( test.error != null )
818          {
819             errorCount ++;
820          }
821       }
822       assertTrue("Thread error count == 0", errorCount == 0);
823    }
824
825    /** Stress test declarative security with the JAAS cache disabled.
826     */

827    public void testStressNoJaasCache() throws Exception JavaDoc
828    {
829       log.info("+++ testStressNoJaasCache, domain=spec-test");
830       // Disable caching for the spec-test domain
831
MBeanServerConnection JavaDoc conn = (MBeanServerConnection JavaDoc) getServer();
832       ObjectName JavaDoc secMgrName = new ObjectName JavaDoc("jboss.security:service=JaasSecurityManager");
833       JaasSecurityManagerServiceMBean secMgr = (JaasSecurityManagerServiceMBean)
834          MBeanServerInvocationHandler.newProxyInstance(conn, secMgrName,
835          JaasSecurityManagerServiceMBean.class, false);
836       secMgr.setCacheTimeout("spec-test", 0, 0);
837
838       Exception JavaDoc failed = null;
839       try
840       {
841          // Now execute the testStress access
842
testStress();
843       }
844       catch(Exception JavaDoc e)
845       {
846          failed = e;
847       }
848
849       secMgr.setCacheTimeout("spec-test", 60, 60);
850       if( failed != null )
851          throw failed;
852    }
853
854    private static class StressTester implements Runnable JavaDoc
855    {
856       InitialContext JavaDoc ctx;
857       int iterations;
858       Throwable JavaDoc error;
859
860       StressTester(InitialContext JavaDoc ctx, int iterations) throws Exception JavaDoc
861       {
862          this.ctx = ctx;
863          this.iterations = iterations;
864       }
865       public void run()
866       {
867          Thread JavaDoc t = Thread.currentThread();
868          Logger log = Logger.getLogger(t.getName());
869          log.info("Begin run, t="+t);
870          try
871          {
872             AppCallbackHandler handler = new AppCallbackHandler(EJBSpecUnitTestCase.username,
873                EJBSpecUnitTestCase.password);
874             for(int i = 0; i < iterations; i ++)
875             {
876                LoginContext JavaDoc lc = new LoginContext JavaDoc("spec-test-multi-threaded", handler);
877                lc.login();
878                Object JavaDoc obj = ctx.lookup("spec.StatelessSession");
879                obj = PortableRemoteObject.narrow(obj, StatelessSessionHome.class);
880                StatelessSessionHome home = (StatelessSessionHome) obj;
881                log.debug("Found StatelessSessionHome");
882                StatelessSession bean = home.create();
883                log.debug("Created spec.StatelessSession");
884                log.debug("Bean.echo('Hello') -> "+bean.echo("Hello"));
885                bean.remove();
886                lc.logout();
887             }
888          }
889          catch(Throwable JavaDoc e)
890          {
891             error = e;
892             log.error("Security failure", e);
893          }
894          log.info("End run, t="+Thread.currentThread());
895       }
896    }
897
898    /** Login as user scott using the conf.name login config or
899     'spec-test' if conf.name is not defined.
900     */

901    private void login() throws Exception JavaDoc
902    {
903       login(username, password);
904    }
905    private void login(String JavaDoc username, char[] password) throws Exception JavaDoc
906    {
907       if( loggedIn )
908          return;
909       
910       lc = null;
911       String JavaDoc confName = System.getProperty("conf.name", "spec-test");
912       AppCallbackHandler handler = new AppCallbackHandler(username, password);
913       log.debug("Creating LoginContext("+confName+")");
914       lc = new LoginContext JavaDoc(confName, handler);
915       lc.login();
916       log.debug("Created LoginContext, subject="+lc.getSubject());
917       loggedIn = true;
918    }
919    private void logout() throws Exception JavaDoc
920    {
921       if( loggedIn )
922       {
923          loggedIn = false;
924          lc.logout();
925       }
926    }
927
928
929    /**
930     * Setup the test suite.
931     */

932    public static Test suite() throws Exception JavaDoc
933    {
934       TestSuite suite = new TestSuite();
935       suite.addTest(new TestSuite(EJBSpecUnitTestCase.class));
936
937       // Create an initializer for the test suite
938
TestSetup wrapper = new JBossTestSetup(suite)
939       {
940          protected void setUp() throws Exception JavaDoc
941          {
942             super.setUp();
943             Configuration.setConfiguration(new XMLLoginConfigImpl());
944             redeploy("security-spec.jar");
945             flushAuthCache();
946          }
947          protected void tearDown() throws Exception JavaDoc
948          {
949             undeploy("security-spec.jar");
950             super.tearDown();
951          
952          }
953       };
954       return wrapper;
955    }
956
957 }
958
Popular Tags