我创建了一个简单的过滤器类,该类为所有请求的资源添加了一些响应标头。 我创建了一个 jar 文件并将其添加到 tomcat lib 文件夹中。此外,过滤器也添加到 Web .xml用于 url 映射/*
当我请求我的应用程序页面时,我可以看到过滤器被调用,因为 sysout 语句打印正确,但标题仅添加到某些资产中。 我很困惑为什么它只被添加到一些资产而不是所有资产中。
过滤器类如下
package com.headers.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MySecurityHeadersFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpResp = (HttpServletResponse) response;
httpResp.addHeader("Content-Security-Policy", "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';base-uri 'self';form-action 'self';");
httpResp.addHeader("Expect-CT", "max-age=86400, enforce, report-uri=https://"+ httpReq.getHeader("host").trim() +"/bham/user/reportCT");
httpResp.addHeader("Feature-Policy", "vibrate 'none'; geolocation 'none';");
httpResp.addHeader("Referrer-Policy", "no-referrer-when-downgrade");
System.out.println("Response Headers: "+((HttpServletResponse) response).getHeaderNames());
}
@Override
public void destroy() {
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.headers.config</groupId>
<artifactId>MySecurityHeadersFilter</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>MySecurityHeadersFilter Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>MySecurityHeadersFilter</finalName>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
任何帮助将不胜感激。
我正在使用 tomcat 9,并在 web.xml 中添加了以下过滤器映射。这是唯一添加的过滤器
<filter>
<filter-name>MySecurityHeadersFilter</filter-name>
<filter-class>com.cdp.headers.config.MySecurityHeadersFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MySecurityHeadersFilter</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>MySecurityHeadersFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>ExpiresFilter</filter-name>
<filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
<init-param>
<param-name>ExpiresByType text/css</param-name>
<param-value>access plus 10 minutes</param-value>
</init-param>
<init-param>
<param-name>ExpiresByType application/javascript</param-name>
<param-value>access plus 10 minutes</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ExpiresFilter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ExpiresFilter</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>
当我执行 URL 时,这是我可以在卡特琳娜日志中看到的。我添加的标头不存在。
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
Response Headers: [Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Accept-Ranges, ETag, Last-Modified, Cache-Control, Expires, Content-Type, Content-Length, Date, Keep-Alive, Connection, Server]
提交响应后,无法设置标头。
筛选器适用于某些请求而不适用于其他请求的原因是,某些请求在筛选器可以添加标头之前提交响应,而有些则不然。
如果将chain.doFilter(request, response);
调用移到设置标头的代码之后,则筛选器应应用于所有内容。
如果要确保后续请求不会更改标头,则有多种选择。提交响应是最简单的,但它是一个相当生硬的工具,可能会破坏一些下游请求(例如,任何试图执行RequestDispatcher.forward()
的请求。更好的解决方案是包装响应并拦截所有标头更改调用并过滤掉您不需要的调用。
对于可能遇到相同问题的任何人,有效的响应包装类如下所示
import java.io.*;
import javax.servlet.http.*;
public class HeaderResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter writer;
public HeaderResponseWrapper(HttpServletResponse response) {
super(response);
writer = new CharArrayWriter();
}
}
doFilter 方法也会改变
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpResp = (HttpServletResponse) response;
HeaderResponseWrapper headerResponseWrapper = new HeaderResponseWrapper(httpResp);
headerResponseWrapper.addHeader("Content-Security-Policy", "default-src 'self'");
chain.doFilter(request, headerResponseWrapper);
对我来说毫无意义,过滤器适用于所有内容,很可能请求没有真正到达服务器,您是否看到浏览器开发人员工具栏中正在调用? 它返回 200 吗?