是否可以将AccessLogValve配置为在将密码写入日志文件之前隐藏/替换密码?我不熟悉阀门,也许有一种方法可以插入自定义过滤器/阀门?
答案 0 :(得分:4)
创建一个单独的maven项目:
<强>的pom.xml 强>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>filtered-access-log-valve</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>7.0.70</version>
</dependency>
</dependencies>
</project>
<强> FilteredAccessLogValve.java 强>
package test;
import org.apache.catalina.valves.AccessLogValve;
public class FilteredAccessLogValve extends AccessLogValve {
@Override
public void log(String message) {
super.log(message.replaceAll("password=[^&]*", "password=***"));
}
}
从项目构建jar工件并将其复制到 tomcat / lib /
在 tomcat / conf / server.xml 中更改访问日志阀类
<Valve className="test.FilteredAccessLogValve" ...>
最后我来到这个解决方案,因为它需要最少的tomcat配置。
<Valve>
标记来关闭默认访问日志阀。创建 AdvancedAccessLogFilter 类:
package your.package;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class AdvancedAccessLogFilter implements Filter {
private static final String PASSWORD_REGEX = "password=[^&]+";
private static final String PASSWORD_MASK = "password=***";
private FilterConfig filterConfig = null;
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
if (filterConfig == null) {
return;
}
HttpServletRequest request = (HttpServletRequest) servletRequest;
String maskedPath = request.getRequestURI()
+ (request.getQueryString() == null ? "" : request.getQueryString().replaceAll(PASSWORD_REGEX, PASSWORD_MASK))
+ " "
+ request.getProtocol();
request.setAttribute("maskedPath", maskedPath);
chain.doFilter(request, servletResponse);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
}
在项目的 web.xml 中注册servlet过滤器:
<filter>
<filter-name>AdvancedAccessLogFilter</filter-name>
<filter-class>your.package.AdvancedAccessLogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AdvancedAccessLogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
使用修改过的访问日志阀模式创建 src / main / webapp / META-INF / context.xml :
<?xml version='1.0' encoding='utf-8'?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Valve
className='org.apache.catalina.valves.AccessLogValve'
directory='logs'
prefix='localhost_access_log.'
suffix='.txt'
pattern='%h %t %m "%{maskedPath}r" %s %b %D'
/>
</Context>
如果要从Spring上下文自动装配某些bean,请添加SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
过滤器的init()
方法。
答案 1 :(得分:0)
简单的答案是扩展AccessLogValve类并覆盖日志方法,使用String#replaceAll将所有出现的密码替换为“ * ”。
答案 2 :(得分:0)
在使用嵌入式 tomcat 服务器的 SAP/Hybris 项目之一中遇到了同样的问题。每当使用密码授予类型进行 oauth/令牌调用时,用户和 OAuth 客户端的机密信息都会以以下格式记录在访问日志中。
0:0:0:0:0:0:0:1 - - [31/Mar/2021:21:19:38 +0530] "POST /authorizationserver/oauth/token?client_id=trusted_client&client_secret=secret&grant_type=password&username=admin&password=nimda HTTP/1.1" 200 334 "-" "PostmanRuntime/7.24.1"
**使用自定义 AccessLogValve 类解决 **
创建一个独立的 Maven 项目。
更新 Pom.xml 如下
4.0.0 过滤访问日志阀 过滤访问日志阀 0.0.1-快照 过滤访问日志阀 过滤访问日志阀用于自定义日志值 org.apache.tomcat tomcat-catalina 8.5.57 Maven 编译器插件 3.5.1 1.8 1.8 org.apache.maven.plugins Maven jar 插件 包裹 罐
在 src/main/java 中创建一个类作为 FilteredAccessLogValve,它扩展了 org.apache.catalina.valves 包中的 AccessLogValve。类如下所示。
包 org.apache.catalina.valves;
导入 java.io.CharArrayWriter; 导入 java.io.IOException;
public class FilteredAccessLogValve extends AccessLogValve {
@Override
public void log(CharArrayWriter message) {
CharArrayWriter caw = new CharArrayWriter();
try {
caw.write(message.toString().replaceAll("password=[^&^ ]*", "password=***").replaceAll("client_secret=[^&^ ]*",
"client_secret=***"));
super.log(caw);
} catch (IOException e) {
e.printStackTrace();
} finally {
caw.close();
}
}
}
使用 mvn clean -> mvn compile -> mvn install 构建 Jar。从/target 文件夹复制filtered-access-log-valve-0.0.1-SNAPSHOT jar 并将其放在hybris/config/customize/platform/tomcat/lib 文件夹中。
查找所有 server.xml hybris/config/tcServer/conf 和 hybris/config/tomcat/conf 文件,并在其中将所有阀门类定义替换为新的 FilteredAccessLogValve 类下面
之前:
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="${HYBRIS_LOG_DIR}/tomcat"
prefix="access."
suffix=".log"
pattern="combined"
/>
之后:
<Valve className="org.apache.catalina.valves.FilteredAccessLogValve"
directory="${HYBRIS_LOG_DIR}/tomcat"
prefix="access."
suffix=".log"
pattern="combined"
/>
在平台中运行ant定制,然后构建并启动服务器。
现在日志看起来像下面这样
0:0:0:0:0:0:0:1 - - [31/Mar/2021:21:19:38 +0530] "POST /authorizationserver/oauth/token?client_id=trusted_client&client_secret=&grant_type=password&username=admin&password= HTTP/1.1" 200 334 "-" "PostmanRuntime/7.24.1"