Testing secured EJBs on JBoss AS7.1.x with Arquillian

When working with EJBs it's sometimes useful to be able to get the caller's authenticated name, make logical decisions based on the callers role or just check that the caller is in an appropriate authorisation role.

 

Typically, your EJB will have a javax.ejb.SessionContext instance variable that has been annotated with @Resource:

 

@Resource
private SessionContext sessionContext 

 

The session bean methods can then call

 

sessionContext.getCallerPrincipal()

 

 

and/or

 

sessionContext.isCallerInRole("someRole")

 

 

as needed.

 

But this means that if you're doing integration testing with Arquillian you will need to somehow set up the proper container security context before invoking the session bean's service methods.

 

The solution to this is to perform a JAAS login from the test.

 

Say we have a session bean that implements this method:

 

public String getCallerPrincipalName() {
     return sessionContext.getCallerPrincipal().getName();
} 

 

 

The test code will then look something like:

 

 
@Test
public void testDiscoverUserName() throws LoginException {
     LoginContext loginContext = JBossLoginContextFactory.createLoginContext("user1", "password"); 
     loginContext.login();
     try {
          String userName = Subject.doAs(loginContext.getSubject(), new PrivilegedAction<String>() {

               @Override
               public String run() {
                    return sut.getCallerPrincipalName();
               } 

          });

          assertEquals("user1", userName); 
     } finally {
          loginContext.logout();
     }
} 

 

 

The JBoss specific setup code is in the JBossLoginContextFactory implementation. Users and roles can be defined in simple users.properties and roles.properties files as described in UsersRolesLoginModule.

 

The same basic technique should work on other application servers. Figuring out the correct JAAS configuration is left as an exercise .

 

The source contains some sample session beans that test not only the methods above, but also the @RolesAllowed, @DenyAll and @PermitAll annotations.

 

Note that these particular annotations only work in JBoss when a security domain has been specified for the application, either in the jboss-ejb3.xml file (which supplants the old jboss.xml) or annotating each relevant bean with @org.jboss.ejb3.annotation.SecurityDomain.

 

In addition, you will need to add a specific security domain to your JBoss configuration (standalone.xml) to specify the correct JAAS Login Module. Add this to the "urn:jboss:domain:security:1.1" subsystem:

 

 <security-domain name="demo" cache-type="default"> 
   <authentication>
      <login-module code="UsersRoles" flag="sufficient"/>
   </authentication>
 </security-domain>

 

 

Source code can be found on GitHub in https://github.com/sfcoy/demos. It is a maven 3 project which can be run from a command line with

 

mvn clean verify

 

 

You will need access to the JBoss maven repository as described in Maven Getting Started - Users.

 

This code has been tested on JBossAS 7.1.0.Final.