私の環境は 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 認証とダイジェスト認証としてデータベースを使用しています。したがって、上記の例に次のコード変更を加える必要がありました。
以下に示すように、「org.jboss.security.auth.spi.DatabaseServerLoginModule」をサポートするようにコード (JBossLoginContextFactory) を変更しました。AppConfigurationEntry[] の作成中に、createUsersRolesLoginModuleConfigEntry() の代わりにこのメソッドを呼び出しています。
private AppConfigurationEntry createDatabaseModuleConfigEntry() { マップ オプション = new HashMap(); options.put("dsJndiName", "java:jboss/datasources/MysqlDS"); options.put("principalsQuery", "プリンシパルからパスワードを選択します。ここで PrincipalID=?"); options.put("rolesQuery", "プリンシパルID=?のロールからロール、ロールグループを選択"); 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"));
これでログイン成功!!