tomcat - 我的自定义 tomcat 阀未被拦截

标签 tomcat tomcat8 access-log tomcat-valve

这是我编写的自定义阀门类。它所做的只是在登录以访问日志文件之前屏蔽密码...

package com.test;

import org.apache.catalina.valves.AccessLogValve;

public class FilteredAccessLogValve extends AccessLogValve {

    public void log(String message) {
        message = message.replaceAll("password=[^&]*", "password=***");
        super.log(message);
    }
}

我将其构建为 value-lib.jar 并复制到 $TOMCAT_HOME/lib 文件夹。

然后我在server.xml中自定义loggin入口在localhost下如下

  <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

    <!-- SingleSignOn valve, share authentication between web applications
         Documentation at: /docs/config/valve.html -->
    <!--
    <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
    -->

    <!-- Access log processes all example.
         Documentation at: /docs/config/valve.html
         Note: The pattern used is equivalent to using pattern="common" -->
    <Valve className="com.test.FilteredAccessLogValve" directory="logs"
           prefix="localhost_access_log" suffix=".txt"
           pattern=" com.test.FilteredAccessLogValve %{X-Forwarded-For}i %h %l %S %u %t '%r' %s %b %D"/>        

           <!-- pattern="%h %l %u %t &quot;%r&quot; %s %b" /-->

  </Host>

现在,我所有的日志请求都像这样正确记录在 localhost_access_log.2018-02-12.txt 文件中

com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:13:49 +0530] 'GET / HTTP/1.1' 200 11452 362
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:13:56 +0530] 'GET /manager/html HTTP/1.1' 401 2536 45
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:14:11 +0530] 'GET /host-manager/html HTTP/1.1' 401 2098 16
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:22:21 +0530] 'GET /host-manager/html HTTP/1.1' 401 2098 132
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:22:22 +0530] 'GET /favicon.ico HTTP/1.1' 200 21630 9
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:24:53 +0530] 'GET / HTTP/1.1' 200 11452 212
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:25:04 +0530] 'GET /?password=123 HTTP/1.1' 200 11452 10
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:10:46:53 +0530] 'GET /ROOT/ HTTP/1.1' 404 1075 52

我面临的问题是,当我将 password=123 之类的参数传递给 URL,例如 http://localhost:8080?password=123 .

我希望它被记录为

com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:11:01:02 +0530] 'GET /?password=*** HTTP/1.1' 200 11452 14

现在记录为

com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - - - [12/Feb/2018:11:01:02 +0530] 'GET /?password=123 HTTP/1.1' 200 11452 14

密码值没有屏蔽。我试图通过远程 Java 应用程序在 jar 的 eclipse 中放置一个调试器,Tomcat 以“jpda 启动”模式启动。

在那里我根本看不到控制被转移到这个类..

所以,我不太清楚它是如何工作的,因为它从我添加到 server.xml 的 XML 配置中获取日志格式,但在同一个 XML 配置中,我提到类名称为“com.test.FilteredAccessLogValve”但这并没有被选中

最佳答案

最后我找到了解决方案。问题是我在开发中使用 tomcat 7 jar 并在 tomcat 8.5 实现中测试解决方案。

Tomcat 在这两个版本之间更改了“AccessLogValve”类中 log() 调用的方法签名。之前是

public void log(String message);

现在修改为

public void log(CharArrayWriter message);

因此我的自定义实现已更改为

package com.test;

import org.apache.catalina.valves.AccessLogValve;

public class FilteredAccessLogValve extends AccessLogValve {

    public void log(CharArrayWriter message) {
        String mymessage = message.toString();
        if(mymessage.toLowerCase().contains("password=")) {
            mymessage = mymessage.replaceAll("password=[^&]*", "password=***");

            CharArrayWriter maskedMessage = new CharArrayWriter(1024);
            try {
                maskedMessage.write(mymessage);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            super.log(maskedMessage);
        } else {
            super.log(message);
        }
    }
}

因为我覆盖了正确的方法,现在这个 http://localhost:8080/manager/html/list?password=123 的日志调用被正确屏蔽,如下所示

com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - C71654B9F585F83AAF6E9A4233BD7D8B tomcat [12/Feb/2018:13:01:06 +0530] 'GET /manager/html/list?password=***
com.test.FilteredAccessLogValve - 0:0:0:0:0:0:0:1 - C71654B9F585F83AAF6E9A4233BD7D8B tomcat [12/Feb/2018:13:01:11 +0530] 'GET /manager/html/list?password=***

关于tomcat - 我的自定义 tomcat 阀未被拦截,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48740145/

相关文章:

tomcat - 将 LDAP 从 Tomcat 转换为 GlassFish

tomcat - 在 Jersey 中调用 tomcat 启动的方法

windows - Tomcat8 无法在 Windows 主机上的 VirtualBox Vagrant 中的 Ubuntu 16.04 中启动

tomcat - 我应该从 Tomcat 7 升级到 Tomcat8 吗?

java - Tomcat使用selenium时无法编译类

java - 如何在 Apache 访问日志中包含精确到毫秒的时间格式

tomcat - tomcat 访问日志中的服务器处理时间

遗留 Java Web 应用程序的 Android 开发

java - catalina.out 连续记录相同的错误

tomcat - tomcat 中特定于应用程序的访问日志?