My environment is Jboss AS 7.1.0. I use JUnit and Arquillian for unit testing. I have SSBs that use the getUserPrincipal () and isCallerInRole () methods in my ejbs. For the unit test of these ejb methods, I need to model the login from the unit test, and then call ejb.
Here is an example of an EJB method that I am trying to verify:
@RolesAllowed({"user","admin"}) public User getMyUserDetails() throws BadInputDataException { String userName = ctx.getCallerPrincipal().getName(); return findUser(userName); }
How to write a JUnit test case to test this method? I appreciate your help in advance.
Updates 07/19 (based on the Tair solution below) :
My security domain configuration:
<security-domains> <security-domain name="other" cache-type="default"> <authentication> <login-module code="Remoting" flag="optional"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> <login-module code="Database" flag="required"> <module-option name="dsJndiName" value="java:jboss/datasources/MysqlDS"/> <module-option name="principalsQuery" value="select Password from Principals where PrincipalID=?"/> <module-option name="rolesQuery" value="select Role, RoleGroup from Roles where PrincipalID=?"/> <module-option name="password-stacking" value="useFirstPass"/> <module-option name="hashAlgorithm" value="MD5"/> <module-option name="hashEncoding" value="RFC2617"/> <module-option name="hashUserPassword" value="false"/> <module-option name="hashStorePassword" value="true"/> <module-option name="passwordIsA1Hash" value="true"/> <module-option name="storeDigestCallback" value="org.jboss.security.auth.callback.RFC2617Digest"/> </login-module> </authentication> </security-domain>
I modified the JBossLoginConfigFactory shown below in Tair to use org.jboss.security.auth.spi.DatabaseServerLoginModule.
I modified JBossLoginConfigFactory to use the following method for DatabaseServerLoginModule.
private AppConfigurationEntry createDatabaseModuleConfigEntry() { Map<String, String> options = new HashMap<String, String>(); options.put("dsJndiName", "java:jboss/datasources/MysqlDS"); options.put("hashAlgorithm", "MD5"); options.put("hashEncoding", "RFC2617"); options.put("hashUserPassword", "false"); options.put("hashStorePassword", "true"); options.put("passwordIsA1Hash", "true"); options.put("storeDigestCallback", "org.jboss.security.auth.callback.RFC2617Digest"); options.put("principalsQuery", "select Password from Principals where PrincipalID=?"); options.put("rolesQuery", "select Role, RoleGroup from Roles where PrincipalID=?"); return new AppConfigurationEntry("org.jboss.security.auth.spi.DatabaseServerLoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); }
and I call this method instead of createUsersRolesLoginModuleConfigEntry (). The loginContext.login () error in the test case fails due to:
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.jboss.security.auth.callback.MapCallback
Not sure what I have to change now!
Update 07/20/2012: A complete solution to the problem is given below. If your solution does not require a DatabaseServerLoginModule, just send the solution back to Tair and thatβs good enough.
In my case, I have a database like JaaS authentication as well as digest authentication. Therefore, I had to make the following code changes to the above example.
I changed the code (JBossLoginContextFactory) to support "org.jboss.security.auth.spi.DatabaseServerLoginModule" as shown below. I call this method instead of createUsersRolesLoginModuleConfigEntry () when creating AppConfigurationEntry [].
private AppConfigurationEntry createDatabaseModuleConfigEntry () {Map parameters = new HashMap (); options.put ("dsJndiName", "java: jboss / datasources / MysqlDS"); options.put ("principalsQuery", "select Password from Principles, where PrincipalID =?"); options.put ("roleQuery", "select Role, RoleGroup from Role, where PrincipalID =?"); return new AppConfigurationEntry ("org.jboss.security.auth.spi.DatabaseServerLoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); }
- When I use digest authentication, my password is encrypted in the database. Therefore, passing the password from my test case, I encrypt and pass the password as shown below. LoginContext loginContext = JBossLoginContextFactory.createLoginContext ("username", md5Hex ("my_username" + ":" + PropertyManager.getProp ("realm") + ":" + "my_password"));
Now the login is completed successfully.