【问题标题】:How to deliver Realm with the war with Tomcat?如何通过与 Tomcat 的战争交付 Realm?
【发布时间】:2015-04-24 12:14:35
【问题描述】:

我们有一个在 Tomcat 7.0.56 上运行的简单 Web 应用程序。现在我们想使用我们的 自己的领域进行身份验证。

public class SpecialAuth extends DataSourceRealm{
    @Override
    public Principal authenticate(String username, String credentials){
        ....
    }
}

这是在war里面的/META-INF/context.xml里面定义的

<Context>
    <Realm className="some.package.SpecialAuth" dataSourceName="jdbc/MySQL" />
</Context>

将 SpecialAuth.class 放在哪里?

我们所期望的只是将 SpecialAuth.class 包含在我们的战争中,但随后我们在启动时遇到了以下异常

Caused by: java.lang.ClassNotFoundException: some.package.BackOfficeAuth
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    ....

如果我们制作一个 jar,将它放入 $TOMCAT/lib 一切正常。

但这不是解决方案!这意味着每次我在这个类上工作时,我都必须触摸我的 tomcat 服务器并且不能使用正常的部署。

如何在不一直触碰tomcat的情况下使用内置的认证机制?

【问题讨论】:

  • 您可能喜欢也可能不喜欢,但$TOMCAT/lib 就是答案。
  • 如果这是唯一的部署方式?你真的关闭tomcat,复制库,​​做其他部署的东西,启动tomcat吗?而不是仅仅部署它?
  • 也可以添加到tomcat启动类路径中。

标签: java tomcat jdbcrealm context.xml


【解决方案1】:

正如你所说,我不喜欢你的回答 :) 所以我所做的(我 100% 确定你不喜欢它)是将领域设置为可能的方式但现在我可以运行它在一个接触过的雄猫上。经过 163 次验收测试后,似乎没有任何问题。

public final class ContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent event) {
        ServletContext servletContext = event.getServletContext();
        TomcatContextManipulator tomcat = new TomcatContextManipulator(servletContext);
        tomcat.applyRealm(new MyOwnRealm());
    }
}

.

public class TomcatContextManipulator {
    private static final String EXPEXCTED_TOMCAT_VERSION = "7.0.52.0";

    private ApplicationContextFacade servletContext;

    /**
     * @param servletContext must be of type {@link ApplicationContextFacade}
     */
    public TomcatContextManipulator(ServletContext servletContext) {
        checkTomcatVersion();

        ensureEquals(servletContext.getClass(), ApplicationContextFacade.class, "class of servletContext");
        this.servletContext = (ApplicationContextFacade) servletContext;
    }

    /**
     * checks if the correct version of tomcat is in use, throws {@link IllegalStateException} if not
     */
    private void checkTomcatVersion() {
        // we use several internal parts of tomcat (for example with reflection)
        // by doing this we bind ourself hardly to a explicit version
        ensureEquals(EXPEXCTED_TOMCAT_VERSION, ServerInfo.getServerNumber(), "Tomcat-Server-Version");
    }

    /**
     * overrides the existing realm with the given on
     */
    public void applyRealm(Realm realm) {
        ensureNotNull(realm, "realm");
        ApplicationContext applicationContext = (ApplicationContext) ReflectionUtil.get(servletContext, "context");
        StandardContext standardContext = (StandardContext) ReflectionUtil.get(applicationContext, "context");
        standardContext.setRealm(realm);
    }
}

注意:

  • Reflection.get() 返回给定对象的(私有)实例变量的值
  • ensure...() 类似于 assert... 但它会抛出异常

【讨论】:

    猜你喜欢
    • 2014-04-28
    • 2016-09-25
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 2016-11-10
    • 2014-10-29
    • 2018-11-03
    • 2012-04-14
    相关资源
    最近更新 更多