4

私の環境は 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 認証とダイジェスト認証としてデータベースを使用しています。したがって、上記の例に次のコード変更を加える必要がありました。

  1. 以下に示すように、「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); }

  2. ダイジェスト認証を使用しているため、パスワードはデータベースで暗号化されています。したがって、テスト ケースからパスワードを渡すときに、以下に示すようにパスワードを暗号化して渡します。LoginContext loginContext = JBossLoginContextFactory.createLoginContext("username", md5Hex("my_username"+":"+PropertyManager.getProp("realm")+":"+"my_password"));

これでログイン成功!!

4

1 に答える 1

1

あなたのケースはこのでカバーされています。基本的には、次のように要約されます。

  1. arquillianContext を使用して、 と の事前設定値で Context を構築しますContext.SECURITY_PRINCIPALContext.SECURITY_CREDENTIALS
  2. そのコンテキストを使用して、EJB への参照を取得します
  3. 試して。

幸運を!

更新: それ以来、Arquillian では多くの変更が加えられたように見えますが、幸いなことに、別の解決策があります。テストして動作確認しました!

于 2012-07-13T12:35:12.760 に答える