【问题标题】:Add Java EE Security Roles dynamically without using deployment descriptor在不使用部署描述符的情况下动态添加 Java EE 安全角色
【发布时间】:2011-04-19 06:10:35
【问题描述】:

我正在使用 Glassfish 3.1、B06 开发一个 Java EE 6 应用程序。 为了保护我的应用程序,我使用了 JDBCRealm 和编程安全性。这可以很好地检查用户名和密码。但是在声明安全角色时,我遇到了一个问题:

要在 Java EE 6 中使用安全角色,我必须在 EJB 部署描述符和 Glassfish 特定部署描述符中声明这些角色以链接这些角色(如 Java EE 6-tutorial 中所述) 只有我可以在 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 部署描述符?还是有更好的方法?

附:还是应该使用 MBeans 添加角色?找到了一个相当相关的帖子here

【问题讨论】:

  • 顺便说一句,我鼓励您升级到更新版本的 GlassFish Server 3.1。该团队最近发布了 build 22。
  • 谢谢。不幸的是,我们有一些库在更高版本的 Glassfish 中出现问题,所以我们必须坚持使用 06,直到这些库中的几个错误得到修复

标签: jakarta-ee glassfish ejb glassfish-3 ejb-3.1


【解决方案1】:

我想出了以下解决方案,以便在登录后以编程方式添加角色,该解决方案至少适用于 GlassFish 3.1.2 build 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);
    }
}

您需要将 GlassFish 中的 security.jarcommon-util.jar 添加到您的项目库中。

不要忘记在您的 web.xml 中为您希望添加的角色创建一个 &lt;security-role&gt; 部分。

请注意,我使用的功能似乎不是已发布的稳定 API 的一部分,因此不能保证这将在 GlassFish 的未来版本中继续工作。

我从GlassFish的sun.appserv.security.AppservPasswordLoginModule.commit()的源代码中得到了关于如何添加角色的信息。 如果将来的 GlassFish 版本破坏了我的代码,这个函数将是一个很好的起点,以便了解如何修复它。

【讨论】:

  • 解决部分问题的好方法。但是,我仍然必须在 web.xml 中静态定义角色。但我想动态添加角色而不必重新启动服务器。我们最终以不同的方式做这件事。记不太清了,但我认为我们用我们自己的替换了 Glassfish 安全机制的很大一部分。
  • 我同意 ifischer。唯一真正的解决方案是不必静态添加任何内容。这应该真正添加到规范中。强制声明曾经似乎是一个好主意,但在实践中它受到严重限制,尤其是在 Glassfish 中非常冗长。
【解决方案2】:

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 不是一个解决方案,但也许这些信息对某人还是有价值的。

【讨论】:

    猜你喜欢
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多