Embedded Glassfish and security issues
nickdegraeve Apr 19, 2011 4:32 AMI'm trying to test my EJB3 on an embedded Glassfish with Arquillian from Maven.
I need to test security and I understand Arquillian doesn't provide a direct way to do that. But I found a discussion (http://community.jboss.org/message/580290) on how it can be done. I followed the instructions but I still got issues:
- my arquillian.xml isn't picked up;
- I got warnings about
@Resource SessionContext;
- I can't get to the running server's instance; maybe as a result of the previous problems
Any help is greatly appreciated.
My EJB:
@Stateless @Local(FileBrowser.class) public class FileBrowserBean implements FileBrowser { @Resource private SessionContext sessionContext; @Override public Set<Application> loadConfiguration() throws FileBrowserException { return ConfigurationHelper.loadConfiguration(this.sessionContext); } }
My JUnit test:
@RunWith(Arquillian.class) public class ArquillianTestCase { @Deployment public static JavaArchive createDeployment() { final JavaArchive jar = ShrinkWrap.create(JavaArchive.class, "test.jar") .addClasses(FileBrowser.class, FileBrowserBean.class).addAsResource("META-INF/ejb-jar.xml") .addAsResource("META-INF/glassfish-ejb-jar.xml"); return jar; } @EJB private FileBrowser fileBrowser; @Test public void setupSecurity() throws Exception { GlassfishTestHelper.createFileUser("user1", "xxx", "role1"); } @Test public void testLoadConfiguration() throws Exception { final boolean loggedIn = GlassfishTestHelper.loginFileUser("user1", "xxx"); Assert.assertEquals(true, loggedIn); this.fileBrowser.loadConfiguration(); } }
GlassfishTestHelper.java:
public final class GlassfishTestHelper { private GlassfishTestHelper() {} public static void createFileUser(final String username, final String password, final String groups) throws Exception { // get the running Arquillian embedded Glassfish server final Server server = Server.getServer(Server.getServerNames().get(0)); final String command = "create-file-user"; final ParameterMap params = new ParameterMap(); params.add("userpassword", password); params.add("groups", groups); params.add("username", username); final CommandRunner runner = server.getHabitat().getComponent(CommandRunner.class); final ActionReport report = server.getHabitat().getComponent(ActionReport.class); runner.getCommandInvocation(command, report).parameters(params).execute(); if (report.getMessage() != null) { throw new Exception(String.format("Failed to create user : %s - message %s", username, report.getMessage()), report.getFailureCause()); } } public static boolean loginFileUser(final String username, final String password) throws Exception { final ProgrammaticLogin login = new ProgrammaticLogin(); return login.login(username, password.toCharArray(), "fileRealm", true); } }
My deployment descriptors with the security are located in src/test/resources/META-INF/.
ejb-jar.xml:
<javaee:ejb-jar version="3.0" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd "> <javaee:enterprise-beans> <javaee:session> <javaee:ejb-name>FileBrowser</javaee:ejb-name> <javaee:ejb-class>com.jnj.gtsc.services.filebrowser.ejb.FileBrowserBean</javaee:ejb-class> <javaee:session-type>Stateless</javaee:session-type> <javaee:security-role-ref> <javaee:role-name>role1</javaee:role-name> </javaee:security-role-ref> </javaee:session> </javaee:enterprise-beans> <javaee:assembly-descriptor> <javaee:security-role> <javaee:role-name>role1</javaee:role-name> </javaee:security-role> </javaee:assembly-descriptor> </javaee:ejb-jar>
glassfish-ejb-jar.xml:
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd"> <glassfish-ejb-jar> <security-role-mapping> <role-name>role1</role-name> <group-name>role1</group-name> </security-role-mapping> <enterprise-beans></enterprise-beans> </glassfish-ejb-jar>
My arquillian.xml is located at src/test/resources and contains:
<arquillian xmlns="http://jboss.com/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:glassfish="urn:arq:org.jboss.arquillian.container.glassfish.embedded_3"> <glassfish:container> <glassfish:bindHttpPort>9090</glassfish:bindHttpPort> <glassfish:instanceRoot>src/test/glassfish</glassfish:instanceRoot> <glassfish:autoDelete>true</glassfish:autoDelete> </glassfish:container> </arquillian>
Relevant Maven dependencies:
org.jboss.arquillian:arquillian-junit:1.0.0.Alpha5:test
org.jboss.arquillian.container:arquillian-glassfish-embedded-3.1:1.0.0.Alpha5:test
org.glassfish.extras:glassfish-embedded-all:3.1:test
When I run my test I get this output:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.jnj.gtsc.services.filebrowser.ArquillianTestCase
19-Apr-2011 10:12:54 org.jboss.arquillian.impl.client.container.ContainerRegistryCreator getActivatedConfiguration
INFO: Could not read active container configuration: null
19-Apr-2011 10:12:55 com.sun.enterprise.v3.server.CommonClassLoaderServiceImpl findDerbyClient
INFO: Cannot find javadb client jar file, derby jdbc driver will not be available by default.
19-Apr-2011 10:12:55 org.hibernate.validator.util.Version <clinit>
INFO: Hibernate Validator null
19-Apr-2011 10:12:55 org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
19-Apr-2011 10:12:56 com.sun.enterprise.v3.services.impl.GrizzlyService createNetworkProxy
INFO: Network listener https-listener on port 0 disabled per domain.xml
19-Apr-2011 10:12:56 com.sun.enterprise.v3.server.AppServerStartup run
INFO: GlassFish Server Open Source Edition 3.1 (java_re-private) startup time : Embedded (1,014ms), startup services(699ms), total(1,713ms)
19-Apr-2011 10:12:56 com.sun.enterprise.v3.services.impl.GrizzlyProxy$2$1 onReady
INFO: Grizzly Framework 1.9.31 started in: 138ms - bound to [0.0.0.0:8181]
19-Apr-2011 10:12:56 org.glassfish.admin.mbeanserver.JMXStartupService$JMXConnectorsStarterThread run
INFO: JMXStartupService: JMXConnector system is disabled, skipping.
19-Apr-2011 10:12:59 com.sun.enterprise.security.SecurityLifecycle <init>
INFO: SEC1002: Security Manager is OFF.
19-Apr-2011 10:12:59 com.sun.enterprise.security.SecurityLifecycle onInitialization
INFO: SEC1010: Entering Security Startup Service
19-Apr-2011 10:12:59 com.sun.enterprise.security.PolicyLoader loadPolicy
INFO: SEC1143: Loading policy provider com.sun.enterprise.security.jacc.provider.SimplePolicyProvider.
19-Apr-2011 10:12:59 com.sun.enterprise.security.auth.realm.Realm doInstantiate
INFO: SEC1115: Realm [admin-realm] of classtype [com.sun.enterprise.security.auth.realm.file.FileRealm] successfully created.
19-Apr-2011 10:12:59 com.sun.enterprise.security.auth.realm.Realm doInstantiate
INFO: SEC1115: Realm [file] of classtype [com.sun.enterprise.security.auth.realm.file.FileRealm] successfully created.
19-Apr-2011 10:12:59 com.sun.enterprise.security.auth.realm.Realm doInstantiate
INFO: SEC1115: Realm [certificate] of classtype [com.sun.enterprise.security.auth.realm.certificate.CertificateRealm] successfully created.
19-Apr-2011 10:12:59 com.sun.enterprise.security.SecurityLifecycle onInitialization
INFO: SEC1011: Security Service(s) Started Successfully
19-Apr-2011 10:13:00 com.sun.enterprise.web.WebContainer createHttpListener
INFO: WEB0169: Created HTTP listener [http-listener] on host/port [0.0.0.0:8181]
19-Apr-2011 10:13:00 com.sun.enterprise.web.WebContainer createHosts
INFO: WEB0171: Created virtual server [server]
19-Apr-2011 10:13:00 com.sun.enterprise.web.WebContainer loadSystemDefaultWebModules
INFO: WEB0172: Virtual server [server] loaded default web module []
19-Apr-2011 10:13:02 org.glassfish.apf.impl.DefaultErrorHandler warning
WARNING: Incorrect @Resource annotation class definition - missing lookup attribute
symbol: FIELD
location: private javax.ejb.SessionContext com.jnj.gtsc.services.filebrowser.ejb.FileBrowserBean.sessionContext
19-Apr-2011 10:13:02 org.glassfish.apf.impl.DefaultErrorHandler warning
WARNING: Incorrect @Resource annotation class definition - missing lookup attribute
symbol: FIELD
location: private javax.ejb.SessionContext com.jnj.gtsc.services.filebrowser.ejb.FileBrowserBean.sessionContext
classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@14e5d57
19-Apr-2011 10:13:02 com.sun.ejb.containers.BaseContainer initializeHome
INFO: Portable JNDI names for EJB FileBrowserBean : [java:global/test/FileBrowserBean!com.jnj.gtsc.services.filebrowser.ejb.FileBrowser, java:global/t
est/FileBrowserBean]
19-Apr-2011 10:13:02 com.sun.enterprise.web.WebApplication start
INFO: WEB0671: Loading application [test] at [/test]
19-Apr-2011 10:13:02 org.glassfish.deployment.admin.DeployCommand execute
PlainTextActionReporterSUCCESSDescription: deploy AdminCommandApplication deployed with name test.
INFO: test was successfully deployed in 4,856 milliseconds.
[name=test
19-Apr-2011 10:13:03 org.jboss.arquillian.testenricher.cdi.CDIInjectionEnricher injectClass
INFO: BeanManager cannot be located at java:comp/BeanManager. Either you are using an archive with no beans.xml, or the BeanManager has not been bound
to that location in JNDI.
19-Apr-2011 10:13:03 org.jboss.arquillian.testenricher.cdi.CDIInjectionEnricher injectClass
INFO: BeanManager cannot be located at java:comp/BeanManager. Either you are using an archive with no beans.xml, or the BeanManager has not been bound
to that location in JNDI.
19-Apr-2011 10:13:03 com.sun.appserv.security.ProgrammaticLogin login
SEVERE: SEC9050: Programmatic login failed
com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Unable to locate a login configuration
at com.sun.enterprise.security.auth.login.LoginContextDriver.doPasswordLogin(LoginContextDriver.java:394)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:240)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:153)
at com.sun.appserv.security.ProgrammaticLogin$1.run(ProgrammaticLogin.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.appserv.security.ProgrammaticLogin.login(ProgrammaticLogin.java:168)
at com.jnj.gtsc.services.filebrowser.util.GlassfishTestHelper.loginFileUser(GlassfishTestHelper.java:67)
at com.jnj.gtsc.services.filebrowser.ArquillianTestCase.testLoadConfiguration(ArquillianTestCase.java:71)
[...]
Caused by: java.lang.SecurityException: Unable to locate a login configuration
at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:93)
[...]
Caused by: java.io.IOException: Unable to locate a login configuration
at com.sun.security.auth.login.ConfigFile.init(ConfigFile.java:250)
at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:91)
... 122 more
classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@14e5d57
PlainTextActionReporterSUCCESSNo monitoring data to report.
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 9.612 sec <<< FAILURE!
Results :
Tests in error:
setupSecurity(com.jnj.gtsc.services.filebrowser.ArquillianTestCase)
testLoadConfiguration(com.jnj.gtsc.services.filebrowser.ArquillianTestCase)
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0
The Maven Surefire report:
-------------------------------------------------------------------------------
Test set: com.jnj.gtsc.services.filebrowser.ArquillianTestCase
-------------------------------------------------------------------------------
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 6.581 sec <<< FAILURE!
setupSecurity(com.jnj.gtsc.services.filebrowser.ArquillianTestCase) Time elapsed: 0.265 sec <<< ERROR!
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at com.jnj.gtsc.services.filebrowser.util.GlassfishTestHelper.createFileUser(GlassfishTestHelper.java:38)
at com.jnj.gtsc.services.filebrowser.ArquillianTestCase.setupSecurity(ArquillianTestCase.java:65)
[...]
testLoadConfiguration(com.jnj.gtsc.services.filebrowser.ArquillianTestCase) Time elapsed: 0.18 sec <<< ERROR!
com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Unable to locate a login configuration
at com.sun.enterprise.security.auth.login.LoginContextDriver.doPasswordLogin(LoginContextDriver.java:394)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:240)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:153)
at com.sun.appserv.security.ProgrammaticLogin$1.run(ProgrammaticLogin.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.appserv.security.ProgrammaticLogin.login(ProgrammaticLogin.java:168)
at com.jnj.gtsc.services.filebrowser.util.GlassfishTestHelper.loginFileUser(GlassfishTestHelper.java:67)
at com.jnj.gtsc.services.filebrowser.ArquillianTestCase.testLoadConfiguration(ArquillianTestCase.java:70)
[...]