如何通过与Tomcat的战争交付Realm



我们有一个在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)
    ....

如果我们制作一个罐子,把它放入$TOMCAT/lib中,一切都很好。

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

如何在不一直接触tomcat的情况下使用内置身份验证机制ß

正如你所说,我不喜欢你的答案:)所以我所做的(我百分之百肯定你不喜欢它)是把这个领域设置在最肮脏的方式上,但现在我可以在一只有经验的tomcat上运行它了。经过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);
    }
}

注:

  • 反射.get()返回给定对象的(私有)实例变量的值
  • 确保。。。()就像断言。。。但它抛出了Exception

相关内容

  • 没有找到相关文章

最新更新