我的环境是 Jboss AS 7.1.0。我正在使用 JUnit 和 Arquillian 进行单元测试。我的 ejb 中有使用 getUserPrincipal() 和 isCallerInRole() 方法的 SSB。为了对这些 ejb 方法进行单元测试,我必须从单元测试用例模拟登录,然后调用 ejb。
这是我正在尝试测试的 EJB 方法的示例:
@RolesAllowed({"user","admin"})
public User getMyUserDetails() throws BadInputDataException {
String userName = ctx.getCallerPrincipal().getName();
return findUser(userName);
}
如何编写 JUnit 测试用例来测试此方法?我提前感谢您的帮助。
07/19 更新(基于以下 Tair 的解决方案):
我的安全域配置如下:
<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>
我将下面 Tair 解决方案中显示的 JBossLoginConfigFactory 更改为使用 org.jboss.security.auth.spi.DatabaseServerLoginModule。
我已将 JBossLoginConfigFactory 更改为对 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);
}
我正在调用此方法而不是 createUsersRolesLoginModuleConfigEntry()。测试用例中的 loginContext.login() 现在由于以下原因而失败:
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.jboss.security.auth.callback.MapCallback
不知道我现在应该改变什么!
2012 年 7 月 20 日更新:该问题的完整解决方案如下。如果您的解决方案不需要 DatabaseServerLoginModule,只需参考 Tair 回复中的解决方案即可。
就我而言,我将数据库作为 JaaS 身份验证和摘要身份验证。因此,我必须对上面的示例进行以下代码更改。
我修改了代码(JBossLoginContextFactory)以支持“org.jboss.security.auth.spi.DatabaseServerLoginModule”,如下所示。我在创建 AppConfigurationEntry[] 时调用此方法而不是 createUsersRolesLoginModuleConfigEntry()。
私有 AppConfigurationEntry createDatabaseModuleConfigEntry() { Map options = new HashMap(); options.put("dsJndiName", "java:jboss/datasources/MysqlDS"); 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); }
- 当我使用摘要身份验证时,我的密码在数据库中被加密。因此,在从我的测试用例中传递密码时,我正在加密并传递密码,如下所示。LoginContext loginContext = JBossLoginContextFactory.createLoginContext("username", md5Hex("my_username"+":"+PropertyManager.getProp("realm")+":"+"my_password"));
现在登录成功了!!