如何在Tomcat上制作服务器范围的过滤器



在工作中,我们继承了这个处理所有SSO登录操作的Java类。有一个FiltroSegurancaGlobal.class被映射到*,强制所有东西都带有注释

@WebFilter(urlPatterns = { "/*" })

该类与其他几个类一起部署在JAR中,以处理整个SSO操作。

最近,我被要求为内部目的安装和配置一个git服务器,我发现了一个非常有趣的解决方案GitBlit,它的工作原理很有魅力。

事情是这样的,当我将它部署到服务器时,不知何故,一些请求通过了过滤器。这似乎是不可能的,所以我把过滤器改为空:

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("filter hit");
}

虽然没有加载整个应用程序,也没有将用户重定向到登录页面,也没有加载任何资源(css,js),但(索引)仍然显示在开发人员工具窗口中的一些页面中。

这怎么可能?部署的带有"/*"urlPatterns的过滤器不是应该过滤所有请求吗?

如下文所述,我尝试先使用注释更改urlPatters,然后再使用服务器的web.xml:

@WebFilter({"/", "*", "/*"})

然后

<filter-mapping>
  <filter-name>FiltroSegurancaGlobal</filter-name>
  <url-pattern>/*</url-pattern>
  <url-pattern>*</url-pattern>
  <url-pattern>/</url-pattern>
</filter-mapping>

一切都没有改变。

通过探测chrome,我意识到似乎唯一通过服务器的文件是angular.js,通过搜索他们的github,我发现了一个NgController.java文件,它有一个奇怪的代码段:

public void renderHead(IHeaderResponse response) {
        // add Google AngularJS reference
        response.renderJavascriptReference(new ResourceReference(NgController.class, "angular.js"));

实际的类还实现了来自ApacheWicket包的IHeaderContributor,不确定这是否有助于解决问题。

我还发现了这个问题,其中提到了FORWARD请求,我想试试看,但我仍然不确定发生了什么。

只是一个小补充,似乎正确的解决方案是使用Tomcat的Valve,但这个问题有一条评论:只有当webapp的/WEB-INF/WEB.xml有另一个具有相同过滤器名称的过滤器时,[过滤器]才是可重写的。

在这种情况下,这是不可能的情况,因为我怀疑部署的应用程序是否具有相同过滤器名称的过滤器映射。

我可能会将整个组件迁移到Valve组件,以确保它在服务器范围内,但我仍然不明白在这个特定的场景中发生了什么。

另外:我忘了提到,当用户尝试连接时,GitBlit有一个控制台输出,例如:2016-05-13 13:53:38 [INFO ] 0 repositories identified with calculated folder sizes in 5 msecs,我刚刚注意到过滤器在它之后执行system.out.println,这意味着浏览器的请求不知何故没有通过它。

在仔细检查这个问题后,我决定将servlet迁移到一个valve。

这是非常直接的。

我只想提一下,我必须添加这两行代码

    HttpServletRequest servletReq = valveReq.getRequest(); 
    HttpServletResponse servletRes = valveRes.getResponse();

为了使Valve按预期工作,因为原始过滤器有一些基于请求的规则,如果没有经过身份验证,它会重定向用户。

我也遇到了同样的问题,尽管我没有找到任何答案,但我自己做了一些测试,得出的结论是Tomcat的web.xml上的/*url映射意味着根上下文以下的任何内容。

假设这是您在Tomcat上部署的:

/ (root application)
/myApp1
/myApp2

如果您随后向URL /myApp1/users发出GET请求,则不会触发筛选器,因为您正在对/myApp1上下文执行操作。

相反,如果您向URL /myApp3/users发出GET请求,那么过滤器将运行,因为现在上下文是/

不幸的是,我说过,除了一些个人测试之外,我没有这个说法的来源,我也不太明白Tomcat默认过滤器应该如何工作,所以请随时反驳我。

最新更新