I want to unit test (actually more of an integration test) my EJB's (3.x). I'm trying to use the Embedded API with Java EE 6 and glassfish v3 to call my EJB. I think it's close to working, it seems to create the bean and such, but my EJB has security constraints via @RolesAllowed annotations, and the first method call is failing because there appears to be no principle, roles, or groups active by default. How do I set this up to login as a particular user or at least specify some allowed roles for the caller?
Do I need to use JAAS or something like that? And if so, how? I do not see any examples anywhere for calling a EJB as a stand alone client that seem to be applicable with the Embedded API like this.
Maybe I could wrap the call with another EJB using @RunAs, but I really do not want to resort to that (if that would work, didn't try it yet).
Maybe there is a "-D" type parameter I need to specify when running the test class?
In case it matters, I using a JDBC realm, however I suspect this issue is independent of that (at least ideally the type of realm should be invisible to the client).
I tried the following, neither of which seemed to solve my problem:
* LoginContext with my own callback handler and with a auth.conf file that had "com.sun.enterprise.security.auth.login.ClientPasswordLoginModule required debug=true;" as the options for the realm.
* ProgrammaticLogin
The first one logged in, but at the EJB level it ignored the subject and had it's own, even when I grabbed and called the bean wrapped by "Subject.doAsPrivileged". The second case would not login, it generated this exception:
Feb 9, 2010 2:02:19 AM com.sun.appserv.security.ProgrammaticLogin login
SEVERE: Programmatic login failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: javax.security.auth.login.LoginException: java.lang.NullPointerException at com.sun.enterprise.security.auth.login.common.ServerLoginCallbackHandler.handle(ServerLoginCallbackHandler.java:93)
at javax.security.auth.login.LoginContext$SecureCallbackHandler$1.run(LoginContext.java:955)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext$SecureCallbackHandler.handle(LoginContext.java:951)
at com.sun.enterprise.security.auth.login.ClientPasswordLoginModule.login(ClientPasswordLoginModule.java:175)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
at com.sun.enterprise.security.auth.login.LoginContextDriver.doPasswordLogin(LoginContextDriver.java:341)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:199)
at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:152)
at com.sun.appserv.security.ProgrammaticLogin$1.run(ProgrammaticLogin.java:161)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.appserv.security.ProgrammaticLogin.login(ProgrammaticLogin.java:155)
Can anyone get this simple example to work using ProgrammaticLogin, LoginContext, or something else, really anything (it works great without the RolesAllowed annotation):