As of September 22, 2017, the version of Spring Security is 4.2.3, so this issue does not occur: sweat :.
** 2018/9/12 postscript: **
** In Spring Security 4.2.5, 5.0.2, the order of filter application → header writing is changed again, so the same problem occurs.
In addition, there is a follow-up report in issue mentioned in the article, and it is flush that the behavior differs depending on the AP server. It looks like the difference between buffer size
and commit size
. ** **
However, it seems that Spring Security is shaking which specification is correct, so be careful when upgrading the version.
When outputting with TERASOLUNA, describe the headers element of Spring Security in spring-security.xml
.
In the example below, the headers applied by default are disabled and only the components that output only the Cache-Control
and X-Content-Type-Options
headers are registered.
spring-security.xml
<sec:http>
<sec:headers defaults-disabled="true">
<sec:cache-control />
<sec:content-type-options />
</sec:headers>
The class that writes the header is ʻorg.springframework.security.web.header.HeaderWriterFilter, which is processed by the
doFilterInternal` method, but the implementation has changed in Spring Security 4.1.0 RC1.
Related issue: SEC-2728: Only write cache related headers if no other cache headers found #2953
↓ 4.0.1. doFilterInternal
method at RELEASE
HeaderWriterFilter.java
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
for (HeaderWriter factory : headerWriters) {
factory.writeHeaders(request, response);
}
filterChain.doFilter(request, response);
}
↓ 4.1.0 doFilterInternal
method at RC1
HeaderWriterFilter.java
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
HeaderWriterResponse headerWriterResponse = new HeaderWriterResponse(request,
response, this.headerWriters);
try {
filterChain.doFilter(request, headerWriterResponse);
}
finally {
headerWriterResponse.writeHeaders();
}
}
In 4.0.1, the processing is done in the order of header writing → filter application, but in 4.1.0, the order is filter application → header writing.
By using try-finally, the header is written even if an exception occurs in the filter application process, but if the http stream is flushed in the filter application process, even if the header is written, it will be written to the client side. Will not be sent. (I couldn't figure out exactly what the problem was when I called the bug report issue: fearful :) The following are the target issues, so please refer to here for details.
Let's upgrade the version of Spring Security: smiley:
If you can't upgrade the version easily, replace HeaderWriterFilter
.
In the bug report issue of ↑, the change of HeaderWriterFilter
is Revert, so HeaderWriterFilter
other than Spring Security 4.1 It is OK if you use.
If you place a HeaderWriterFilter
other than Spring Security 4.1 in com.neriudon.sample.filter
and name it CustomizedHeaderWriterFilter
, it will look like this:
spring-security.xml
<bean id="secureCacheControlHeadersWriter"
class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<constructor-arg>
<bean
class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/**" />
</bean>
</constructor-arg>
<constructor-arg>
<bean
class="org.springframework.security.web.header.writers.CacheControlHeadersWriter" />
</constructor-arg>
</bean>
<bean id="customizedHeaderWriterFilter" class="com.neriudon.sample.filter.CustomizedHeaderWriterFilter">
<constructor-arg ref="secureCacheControlHeadersWriter" />
</bean>
<sec:http>
<sec:headers disabled="true" />
<sec:custom-filter position="HEADERS_FILTER"
ref="customizedHeaderWriterFilter" />
The point is
<sec:headers disabled="true" />
<sec:custom-filter position="HEADERS_FILTER"
ref="customizedHeaderWriterFilter" />
It is the part of.
You can use position
to replace it with your own filter, but you have to setheaders disabled = "true"
because it conflicts with existing filters.
Therefore, the header to be output to the filter to be replaced is specified. This part is quoted from Output security header for each request pattern in TERASOLUNA guidelines. Did.
When I raised the version of TERASOLUNA, the header was no longer output, so: frowning2: There is a comment that the behavior is different in Tomcat / JBoss even in the bug report issue, but ... It's deep: disappointed_relieved:
Recommended Posts