Пользовательский фильтр сервлетов не применяется ко всем ресурсам - PullRequest
0 голосов
/ 30 мая 2020

Я создал простой класс Filter, который добавляет некоторые заголовки ответов ко всем запрошенным ресурсам. Я создал файл jar и добавил его в папку lib tomcat. Также фильтр добавляется в Интернет. 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 и добавил ниже сопоставление фильтров в сети. 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, это то, что я вижу в журналах catalina. Заголовки, которые я добавил, отсутствуют.

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]

Ответы [ 3 ]

0 голосов
/ 02 июня 2020

Вы не можете устанавливать заголовки после подтверждения ответа.

Причина, по которой ваш фильтр работает для некоторых запросов, а не для других, заключается в том, что некоторые запросы фиксируют ответ до того, как ваш фильтр сможет добавить заголовки, а некоторые нет .

Если вы переместите вызов chain.doFilter(request, response); после кода, в котором вы устанавливаете заголовки, фильтр должен применяться ко всему.

Если вы хотите гарантировать, что последующие запросы не изменятся заголовки, у вас есть несколько вариантов. Фиксация ответа является самым простым, но это довольно грубый инструмент и может нарушить некоторые из нисходящих запросов (например, любой, который пытается выполнить RequestDispatcher.forward(). Лучшее решение - обернуть ответ и перехватить все вызовы, изменяющие заголовок, и отфильтровать выбери те, которые тебе не нужны.

0 голосов
/ 03 июня 2020

Класс-оболочка Response, который работал, как показано ниже для всех, кто может столкнуться с той же проблемой

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);
0 голосов
/ 30 мая 2020

Для меня это не имеет смысла, фильтр применяется ко всему, есть вероятность, что запрос действительно не доходит до сервера, вы видите, что вызов делается на панели инструментов разработчика браузера? он возвращает 200 ?.

...