How to write a JUnit test when I use the getUserPrincipal () and isCallerInRole () method in an enterprise bean?

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.

+4
source share
1 answer

Your case is examined in this example . It basically boils down to:

  • Use arquillianContext to create a Context with predefined values ​​for Context.SECURITY_PRINCIPAL and Context.SECURITY_CREDENTIALS
  • Use this context to get a link to you EJB
  • Check it out.

Good luck

UPDATE: it looks like Arkillian has changed a lot since then, fortunately, we have another solution . I tested it and confirmed that it works!

+1
source

All Articles