10

Glassfish 3.1、B06 を使用して Java EE 6 アプリケーションを開発しています。アプリを保護するために、JDBCRealm とプログラムによるセキュリティを使用しています。これは、ユーザー名とパスワードをチェックするのにうまく機能します。しかし、セキュリティ ロールの宣言に関しては、次のような問題があります。

Java EE 6 でセキュリティ ロールを使用するには、EJB デプロイメント記述子と Glassfish 固有のデプロイメント記述子の両方でこれらのロールを宣言して、それらのロールをリンクする必要があります ( Java EE 6 チュートリアルで説明されているように) EJB 内のメソッドisCallerInRole(String roleRef)を使用して権限を確認します。

これは私のアプリケーションには望ましくありません。XML ファイルを作成せずに (たとえば、データベースでロール名を定義できるようにするなど)、セキュリティ ロールを動的かつプログラム的に追加できるようにしたいからです。

GF3 ソース コードをデバッグしたところ、 com.sun.ejb.containers.EjbContextImplに isCallerInRole が実装されていることがわかりました。そこで、コンテナーは EJB 記述子からロールを取得します。

public boolean isCallerInRole(String roleRef) {
  (...)
  EjbDescriptor ejbd = container.getEjbDescriptor();
  RoleReference rr = ejbd.getRoleReferenceByName(roleRef);
  (...)
}

周りを見回したところ、アプリケーション内でどうにかして EJB 記述子を取得できれば、次のようなロールを追加できることがわかりました。

EjbDescriptor ejbd = //??? Can i use that descriptor inside my app, or is that "forbidden"?
RoleReference rr = new RoleReference("admin", "Admins are allowed to do everything");
ejbd.addRoleReference(rr);

誰かがこのようなことをしたり、それについて考えたりしましたか? アプリケーション内で EJB デプロイメント記述子を使用することはできますか? または、より良いアプローチがありますか?

PSまたはMBeanを使用してロールを追加する必要がありますか? ここでかなり関連する投稿を見つけました。

4

2 に答える 2

3

ログイン後にプログラムでロールを追加する次のソリューションを思いつきました。これは、少なくとも GlassFish 3.1.2 ビルド 23 で動作します。

import com.sun.enterprise.security.SecurityContext;
import com.sun.enterprise.security.web.integration.PrincipalGroupFactory;
import java.security.Principal;
import java.util.Set;
import javax.security.auth.Subject;
import org.glassfish.security.common.Group;

public class GlassFishUtils {
    public static void addGroupToCurrentUser(String groupName, String realmName) {
        Subject subject = SecurityContext.getCurrent().getSubject();
        Set<Principal> principals = subject.getPrincipals();
        Group group = PrincipalGroupFactory.getGroupInstance(groupName, realmName);
        if (!principals.contains(group))
            principals.add(group);
    }
}

security.jarおよびcommon-util.jarGlassFish からプロジェクト ライブラリに追加する必要があります。

<security-role>また、追加したいロールのセクションを web.xml に作成することを忘れないでください。

公開された安定した API の一部ではないように見える機能を使用しているため、GlassFish の将来のリリースでこれが機能し続けるという保証はありません。

sun.appserv.security.AppservPasswordLoginModule.commit()GlassFishのソースコードから役割を追加する方法についての情報を入手しました。将来の GlassFish リリースで私のコードが壊れた場合、この関数は修正方法を見つけるために開始するのに適した場所です。

于 2012-07-11T08:04:14.983 に答える
3

Javadoc では、この要件について明示的に言及しています。

   /**
    * Tests if the caller has a given role.
    *
    * @param roleName - The name of the security role. The role must be one of the security roles that
    * is defined in the deployment descriptor.
    * @return True if the caller has the specified role.
    */
   public boolean isCallerInRole(String roleName);

しかし、少なくとも JBoss AS では、これらのロールを事前に宣言する必要がないことがわかりました。この場合、主な役割はシステム内で動的に作成され、認証が行われるときに割り当てられます。したがって、それらを事前に宣言することは不可能です。

それでも、isCallerInRole メソッドは完璧に機能します。

JBoss AS への切り替えが解決策ではないことは理解していますが、この情報は誰かにとって価値があるかもしれません。

于 2011-02-12T19:06:19.217 に答える