我在Glassfish 4中运行了Jackrabbit 2.6.4。我使用提供的rar将Jackrabbit部署为连接器资源。
我已经启动并运行,以便我可以从无状态EJB中调用Jackrabbit存储库并可以创建节点等。我现在正在尝试使用我自己的自定义替换开箱即用的Default LoginModule机制的LoginModule。
到目前为止,我有:
创建一个Custom Realm和LoginModule,它返回用户原则(当前为String值,例如admin,read,write),并将其部署到domain / lib目录
配置我的web.xml和sun-web.xml文件,其中包含用于分组映射和启用基本身份验证的角色。这一切都按预期工作,我可以在我的EJB上强制执行角色。
让Jackrabbit使用我的自定义登录模块而不是它自己(我从repository.xml中删除了登录模块配置并更改了安全应用程序名称以匹配我的领域名称)
我现在遇到以下问题:
当我登录时,Jackrabbit找不到应用程序容器创建的现有主题。这似乎与Jackrabbit查找主题的方式有关:
AccessControlContext acc = AccessController.getContext();
subject = Subject.getSubject(acc);
这在Glassfish中返回null。相反,它似乎需要使用:
Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
我通过使用上面的代码获取主题然后登录到Subject.doAs块内的存储库来解决这个问题,例如。
Subject.doAs(subject, new PrivilegedAction<String>() {
@Override public String run() {
Session session = null;
try {
session = repository.login();
} catch (RepositoryException e) {
log.error("Failed", e);
} finally {
if (session != null) {
session.logout();
}
}
这现在有效但下一个问题是JackRabbit DefaultAccessManager要求Subject包含JackRabbit类型的原则,例如: org.apache.jackrabbit.core.security.SystemPrincipal,我无法从自定义登录模块返回,因为它无法访问JackRabbit类。
我第一次尝试解决这个问题的方法是创建自己的AccessManager,但JackRabbit无法实例化它,因为它在我的WAR中,并且不可用于连接器资源中的JackRabbit代码。
我的下一次尝试是在将它传递给Jackrabbit之前以编程方式将原理添加到我的EJB中的Subject,这有效但后来我发现在glassfish中的EJB内运行Subject.doAs会导致许多问题而不会似乎得到了支持。 Jackrabbit内部还有背景线程,需要一个符合JackRabbit类型原则的主题。
我现在完全不知道如何使用自定义JAAS glassfish登录模块与Glassfish中的Jackrabbit一起工作,我想知道是否有人知道这一点。
与此同时,我正在考虑放弃JackRabbit的安全性,并在我的应用层处理所有内容,只需使用默认的登录模块登录Jackrabbit。
答案 0 :(得分:0)
我终于让Glassfish,JackRabbit和JAAS一起工作,这样我就可以使用JackRabbit用来创建会话的自定义LoginModule创建一个Subject。以下是我为解决原始问题中描述的问题而采取的步骤:
我现在在战争中加入了JackRabbit Jars(Model 2),而不是使用JackRabbit RAR(Model 1)。这允许我实现我自己的自定义AccessManager,它不依赖于JackRabbit类型的原则。这种方法的最大缺点是我现在必须自己创建和关闭存储库。我使用的解决方案是ApplicationScoped CDI Producer,它创建repo并在dispose方法中关闭它。这使得将repo注入类中变得容易。
我解决了JackRabbit通过修补长耳兔核心找到Glassfish中的主题的问题。这个问题似乎已经存在了一段时间(JCR-3188),并且已经提供了补丁但从未包含在源代码中。我将补丁应用到2.6.4,JackRabbit现在可以在Glassfish中找到并使用Subject。