I have a @RolesAllowed protected @Stateless EJB that I'm trying to JUnit-4 test with embedded GlassFish container. The most recent hurdle I've overcoming has been GlassFish domain configuration for persistence unit and security realm.
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(EJBContainer.MODULES, new File("build/classes"));
properties.put("org.glassfish.ejb.embedded.glassfish.configuration.file",
"test-resource/domain.xml");
ec = javax.ejb.embeddable.EJBContainer.createEJBContainer(properties);
Embedded GlassFish starts, my application deploys, and everything seems to work as expected until I call a EJB method with a @RolesAllowed annotation.
javax.ejb.AccessLocalException: Client not authorized for this invocation
For some reason I can not figure out how to set the container's role to pass the security check. What am I missing?
You can use the com.sun.appserv.security.ProgrammaticLogin
class to help you out with this. This is specific to GlassFish, and not a Java EE 6 API; if you're using a different embedded container, you'll need to find the equivalent one.
ProgrammaticLogin
enables you to login as a user and establish a security principal for the current thread. An example of it's usage would be:
ProgrammaticLogin login = new ProgrammaticLogin();
login.login("user", "password", "file", true);
where user
and password
are the credentials to be used to login as a user in the file
realm. This allows you to establish a security principal to be utilized when invoking an EJB deployed in the embedded container. The absence of this would result in the anonymous principal being used for as the principal (thus resulting in an exception when the container enforces the RolesAllowed
constraints).
Note, that this also requires you to use an existing security realm. It is recommended that you use a custom GlassFish install root (or instance root) that contains a pre-configured domain.xml
file with the security realm used by your application.
Some more details on how to use the ProgrammaticLogin
API can be found in this Oracle blog entry.