国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

HTTP安全頭部對jsp頁面不生效

這篇具有很好參考價(jià)值的文章主要介紹了HTTP安全頭部對jsp頁面不生效。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本文于2016年4月底完成,發(fā)布在個(gè)人博客網(wǎng)站上。
考慮個(gè)人博客因某種原因無法修復(fù),于是在博客園安家,之前發(fā)布的文章逐步搬遷過來。


詭異的問題

AppScan掃描報(bào)告中提示,Web服務(wù)器返回js、csspng、jsp頁面的HTTP響應(yīng)中缺少安全頭部。HTTP的安全頭部包括HTTP Strict Transport Security、X-Frame-Options、X-Content-Type-Options、X-XSS-Protection、Content-Security-Policy

網(wǎng)上資料很多,于是參照資料修改$CATALINA_BASE/conf/web.xml,增加相關(guān)配置,如下是樣例:

<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>  <!-- 注意:Jackie遇到的問題與httpHeaderSecurity的配置相關(guān)。 -->
</filter-mapping>

本以為這樣修改之后問題就解決了,所以也沒用瀏覽器的調(diào)試面板去仔細(xì)檢查Web服務(wù)器響應(yīng)數(shù)據(jù)的HTTP頭部;但天不遂人愿,事情并沒有如預(yù)想的方向發(fā)展。

在稍后的一份AppScan掃描報(bào)告中,居然又看到了Web服務(wù)器返回的HTTP響應(yīng)缺少安全頭部的提示。不過這次稍有區(qū)別,報(bào)告中只提示jsp頁面的訪問存在問題。于是使用瀏覽器的調(diào)試面板仔細(xì)查看Web服務(wù)器返回的響應(yīng)信息,發(fā)現(xiàn)Web服務(wù)器返回jscss、png時(shí),在HTTP響應(yīng)中增加了必要的頭部,如下所示:

Cache-Control:private
Content-Type:image/png
Date:Sun, 10 Apr 2016 13:16:26 GMT
Expires:Thu, 01 Jan 1970 08:00:00 CST
Server:Apache-Coyote/1.1
Strict-Transport-Security:max-age=0
Transfer-Encoding:chunked
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

這說明安全頭部的配置生效了,但詭異的是jsp頁面的響應(yīng)中并沒有相應(yīng)增加安全頭部,如下所示,導(dǎo)致AppScan報(bào)告中Web服務(wù)器返回的HTTP響應(yīng)缺少安全頭部問題依然存在。

Content-Type:text/html;charset=UTF-8
Date:Tue, 24 May 2016 16:18:30 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked

同部門內(nèi)有一個(gè)A項(xiàng)目,這個(gè)項(xiàng)目有10年開發(fā)、維護(hù)的歷史,歷經(jīng)公司安全紅線多輪整改,項(xiàng)目成員積累了相當(dāng)豐富的斗爭經(jīng)驗(yàn),在處理AppScan掃描報(bào)告上也有相當(dāng)?shù)慕?jīng)驗(yàn)。于是就安全頭部的整改方法咨詢A項(xiàng)目的MDE,希望可以獲得關(guān)鍵信息。

A項(xiàng)目的MDE為人很爽快,介紹了他們的經(jīng)驗(yàn),總結(jié)下有如下幾點(diǎn):

  • A項(xiàng)目在整改AppScan掃描問題時(shí),確實(shí)遇到過類似的問題,解決的方法是給響應(yīng)增加安全頭部。
  • 但A項(xiàng)目使用了自定義的過濾器來給HTTP響應(yīng)增加安全頭部,并沒有使用Apache Tomcat官方提供的過濾器,原因是A項(xiàng)目使用的Tomcat版本太低,出于業(yè)務(wù)原因暫不好升級。
  • A項(xiàng)目增加自定義的過濾器之后,“Web服務(wù)器返回的HTTP響應(yīng)缺少安全頭部”就從AppScan掃描報(bào)告中消失了。

但壞消息是A項(xiàng)目團(tuán)隊(duì)沒有遇到過前述的問題,自然沒有處理類似問題的經(jīng)驗(yàn)可供參考。這就詭異了,為什么Web服務(wù)器對jsp的響應(yīng)沒有增加安全頭部呢?

分析過程

當(dāng)前的項(xiàng)目使用了Spring+Struts2+iBatis,從技術(shù)組合上可以說非常傳統(tǒng),但在技術(shù)應(yīng)用上存在很大不同。為了描述方便,下面把存在問題的項(xiàng)目稱為B項(xiàng)目。

檢查項(xiàng)目配置

重溫項(xiàng)目的配置情況。

Struts2的配置

Struts2在web.xml中的配置如下:

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

簡化后的struts.xml配置文件,內(nèi)容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.action.extension" value="jsp,action"/> <!-- 注意這里 -->
    <constant name="struts.ui.theme" value="java"></constant>
    <constant name="struts.objectFactory" value="spring" />
    <constant name="struts.i18n.encoding" value="UTF-8" />
    <package name="default" namespace="/" extends="struts-default">

        <interceptors>
            <interceptor-stack name="myStack">  
                <interceptor-ref name="basicStack"></interceptor-ref>  
            </interceptor-stack> 
        </interceptors>  
  
        <default-interceptor-ref name="myStack" /> 
        
        <global-results>
            <result name="error">/error.jsp</result>
        </global-results>

        <global-exception-mappings>
            <exception-mapping exception="java.lang.Exception" result="error"/>
        </global-exception-mappings>

        <action name="*" class="MainAction">
            <result name="success">{1}.jsp</result>
        </action>
    </package>
</struts>

通用Action類,簡化后的MainAction代碼如下

import com.opensymphony.xwork2.ActionSupport;

public class MainAction extends ActionSupport {
	private static final long serialVersionUID = 928135783255954591L;
	@Override
	public String execute() throws Exception {
		return ActionSupport.SUCCESS;
	}
}

粗看下來,似乎沒有什么不妥的地方。

安全頭部的配置

依照文檔,重新檢查$CATALINA_BASE/conf/web.xml文件中的配置,如下:

<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>

沒看出來什么特別的地方,而官方文檔對HttpHeaderSecurityFilter的使用也沒有特別的說明,那是不是HttpHeaderSecurityFilter的實(shí)現(xiàn)代碼中有玄機(jī)?

找到HttpHeaderSecurityFilter類的代碼,如下是增加頭部的實(shí)現(xiàn)。

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {

    if (response instanceof HttpServletResponse) {
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        if (response.isCommitted()) {
            throw new ServletException(sm.getString("httpHeaderSecurityFilter.committed"));
        }

        // HSTS
        if (hstsEnabled && request.isSecure()) {
            httpResponse.setHeader(HSTS_HEADER_NAME, hstsHeaderValue);
        }

        // anti click-jacking
        if (antiClickJackingEnabled) {
            httpResponse.setHeader(ANTI_CLICK_JACKING_HEADER_NAME, antiClickJackingHeaderValue);
        }

        // Block content type sniffing
        if (blockContentTypeSniffingEnabled) {
            httpResponse.setHeader(BLOCK_CONTENT_TYPE_SNIFFING_HEADER_NAME,
                    BLOCK_CONTENT_TYPE_SNIFFING_HEADER_VALUE);
        }

        // cross-site scripting filter protection
        if (xssProtectionEnabled) {
            httpResponse.setHeader(XSS_PROTECTION_HEADER_NAME, XSS_PROTECTION_HEADER_VALUE);
        }
    }

    chain.doFilter(request, response);
}

代碼很簡單,沒發(fā)現(xiàn)對jsp的訪問有做過什么特別的處理。

對頁面訪問的影響

依據(jù)前述配置,頁面訪問流程如下所示:

  • 瀏覽器請求頁面時(shí),Web服務(wù)端的Struts2攔截頁面訪問請求;
  • Web服務(wù)端的通用Action接收請求,并將請求重定向至對應(yīng)的jsp頁面;
  • 由于沒有使用Action向頁面?zhèn)鬟f數(shù)據(jù),所以開發(fā)人員需要在頁面上使用ajax方式向Web服務(wù)端請求業(yè)務(wù)數(shù)據(jù);

進(jìn)一步分析

仔細(xì)回想了A項(xiàng)目的特點(diǎn),以及與B項(xiàng)目的差異點(diǎn)。

A項(xiàng)目也使用了Spring+Struts的組合,但和B項(xiàng)目有個(gè)顯著不同點(diǎn),B項(xiàng)目是Struts2的重度使用用戶,項(xiàng)目中的jsp全部使用action做了包裝,用戶在地址欄看不到jsp結(jié)尾的URL。

而B項(xiàng)目雖然使用了Spring+Struts的組合,但實(shí)際上僅僅使用了Struts2提供的國際化和s標(biāo)簽,代碼中定義的Action僅用于轉(zhuǎn)發(fā)請求至jsp,用戶在瀏覽器的地址欄里可以明確的看到當(dāng)前頁面的jsp文件名和路徑。

如下是A項(xiàng)目struts.xml文件中action后綴的配置

<constant name="struts.action.extension" value="action"/>

如下是B項(xiàng)目struts.xml文件中action后續(xù)的配置

<constant name="struts.action.extension" value="jsp,action"/>

問題在于A項(xiàng)目并沒有遇到B項(xiàng)目現(xiàn)在遇到的問題。

分析到這里,嘗試調(diào)整struts.xml的配置,去掉配置中的jsp,如下所示

<constant name="struts.action.extension" value="action"/>

這樣action后綴的配置和A項(xiàng)目保持一致。

重啟應(yīng)用之后,使用Google Chrome提供的調(diào)試面板,檢查Web服務(wù)器對jsp頁面的響應(yīng),發(fā)現(xiàn)居然有HTTP安全頭部。這說明,action后綴的配置對安全頭部的生成有影響,但具體什么影響還未知,并且出于技術(shù)原因,目前并不能調(diào)整action后綴的配置。因此這問題還不算完,需要繼續(xù)分析。

依據(jù)J2EE規(guī)范中Filter和Servlet的定義,我們知道Filter在執(zhí)行時(shí)需要等待Servlet完成處理并寫出響應(yīng)后才會逐個(gè)返回,因此觀察Servlet的運(yùn)行棧,可以看到Web請求的處理路徑。既然調(diào)整action后綴的配置對安全頭部的生成有影響,那么說明不同的配置條件下,jsp的執(zhí)行路徑是有差異的,因此觀察運(yùn)行棧一定可以發(fā)現(xiàn)點(diǎn)什么。

但問題是對于代碼里的Servlet類,可以使用eclipse的調(diào)試手段,在代碼里打上斷點(diǎn),觀察執(zhí)行棧,但對于jsp來說,使用打斷點(diǎn)來檢查棧的方法就行不通了。那怎么辦呢?

其實(shí)方法很簡單,jsp頁面內(nèi)可以寫Java代碼,因此可以在頁面上定義一個(gè)java.lang.Throwable對象,然后使用該對象來輸出當(dāng)前調(diào)用棧。代碼樣例如下所示:

<%
	new Throwable().printStackTrace();
%>

于是調(diào)整action后綴的配置,使用瀏覽器訪問頁面,提取頁面生成的棧。

如下是action后綴配置為jsp,action時(shí)的棧。

java.lang.Throwable
at org.apache.jsp.index_jsp._jspService(index_jsp.java:115)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:232)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:64)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:702)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:450)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:375)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:164)
at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:372)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:276)
at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:567)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:105)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1078)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:757)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1520)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

如下是action后綴配置為action時(shí)的棧。

java.lang.Throwable
at org.apache.jsp.index_jsp._jspService(index_jsp.java:115)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:232)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:120)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:105)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1078)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:757)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1520)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

對比之下,有如下發(fā)現(xiàn):

  • 當(dāng)action后續(xù)為jsp,action時(shí)

    • 棧信息很長。
    • 棧中出現(xiàn)了很多Struts2相關(guān)的棧幀(stack frame),說明頁面訪問請求被Struts2的過濾器攔截,符合預(yù)期。
    • 棧中未出現(xiàn)HttpHeaderSecurityFilter相關(guān)的棧幀(stack frame)。
    • Log4jServletFilter相關(guān)的棧幀(stack frame)出現(xiàn)了兩次,為什么?
  • 當(dāng)前action后綴為action時(shí)

    • 棧信息很短。
    • 棧中沒有Struts2相關(guān)的棧幀(stack frame),說明頁面訪問請求沒有被被Struts2的過濾器攔截,符合預(yù)期。
    • 棧中出現(xiàn)了HttpHeaderSecurityFilter相關(guān)的棧幀(stack frame)。
    • Log4jServletFilter相關(guān)的棧幀(stack frame)出現(xiàn)了一次,有點(diǎn)意思。

舊的問題沒解決,新的問題又出現(xiàn)了。action后綴的配置,看來不單對HttpHeaderSecurityFilter產(chǎn)生了影響,對Log4jServletFilter的行為也有影響。

于是檢查Log4jServletFilter的配置,如下

<listener>   
   <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
</listener>   

 <!-- log4j2-begin -->
 <listener>
     <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
 </listener>
 <filter>
     <filter-name>log4jServletFilter</filter-name>
     <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
 </filter>
 <filter-mapping>
     <filter-name>log4jServletFilter</filter-name>
     <url-pattern>/*</url-pattern>
     <dispatcher>REQUEST</dispatcher>
     <dispatcher>FORWARD</dispatcher>
     <dispatcher>INCLUDE</dispatcher>
     <dispatcher>ERROR</dispatcher>
 </filter-mapping>  

咦,怎么filter-mapping還可以配置dispatcher,這是什么鬼?先不管它,參照Log4jServletFilter的配置,修改HttpHeaderSecurityFilter的配置信息。

<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>
	<dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

重啟應(yīng)用之后使用瀏覽器的調(diào)試面板觀察頁面的響應(yīng)數(shù)據(jù),久違的HTTP安全頭部終于出現(xiàn)了。

Content-Type:text/html;charset=UTF-8
Date:Tue, 24 May 2016 16:15:21 GMT
Server:Apache-Coyote/1.1
Strict-Transport-Security:max-age=0
Transfer-Encoding:chunked
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

這時(shí),檢查棧信息,可以看到HttpHeaderSecurityFilter相關(guān)的棧幀(stack frame)。

java.lang.Throwable
at org.apache.jsp.index_jsp._jspService(index_jsp.java:115)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:232)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:120)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:64)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:702)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:450)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:375)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:164)
at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:372)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:276)
at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:567)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:105)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1078)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:757)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1520)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

定位結(jié)論

折騰這么久,終于把解決方法整出來了,其實(shí)很簡單。

當(dāng)前struts.xml中有如下配置

<constant name="struts.action.extension" value="action,jsp"/>

配置安全頭部的過濾器時(shí),需要在URL匹配模式上增加REQUESTFORWARD。

<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>
	<dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

原因應(yīng)該和Struts2重定向請求至頁面的方式相關(guān),不過暫時(shí)沒有時(shí)間去研究Struts2,期望后續(xù)會有所了解。

資料

關(guān)于dispatcher的一些資料。文章來源地址http://www.zghlxwxcb.cn/news/detail-779072.html

  • web.xml里中的作用
  • Web.xml中Filter過濾器標(biāo)簽幾個(gè)說明
  • filter-mapping的執(zhí)行順序和字符集設(shè)置的優(yōu)先級
  • Filtering Requests and Responses

到了這里,關(guān)于HTTP安全頭部對jsp頁面不生效的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 什么是HTTP頭部(HTTP headers)?

    什么是HTTP頭部(HTTP headers)?

    前端入門之旅:探索Web開發(fā)的奇妙世界 歡迎來到前端入門之旅!感興趣的可以訂閱本專欄哦!這個(gè)專欄是為那些對Web開發(fā)感興趣、剛剛踏入前端領(lǐng)域的朋友們量身打造的。無論你是完全的新手還是有一些基礎(chǔ)的開發(fā)者,這里都將為你提供一個(gè)系統(tǒng)而又親切的學(xué)習(xí)平臺。在這個(gè)

    2024年02月07日
    瀏覽(24)
  • HTTP 頭部- Origin Referer

    Origin Header 示例 Origin 請求頭部是一個(gè) HTTP 頭部,它提供了發(fā)起請求的網(wǎng)頁的源(協(xié)議、域名和端口)信息。它通常在進(jìn)行跨域資源共享(CORS)請求時(shí)使用,以便服務(wù)器可以決定是否接受請求。 假設(shè)我們在瀏覽器的地址欄輸入并訪問 http://www.example.com ,這個(gè)網(wǎng)站上有一個(gè) AJ

    2024年02月21日
    瀏覽(25)
  • http請求頭部(header)詳解

    http請求頭部(header)詳解

    通常HTTP消息包括客戶機(jī)向服務(wù)器的請求消息和服務(wù)器向客戶機(jī)的響應(yīng)消息。這兩種類型的消息由一個(gè)起始行,一個(gè)或者多個(gè)頭域,一個(gè)只是頭域結(jié)束的空行和可 選的消息體組成。HTTP的頭域包括通用頭,請求頭,響應(yīng)頭和實(shí)體頭四個(gè)部分。每個(gè)頭域由一個(gè)域名,冒號(:)和域

    2024年02月12日
    瀏覽(20)
  • HTTP頭部信息解釋(超級詳細(xì))

    本篇文章將會詳細(xì)的介紹HTTP頭部信息,若大家在使用過程中有不了解的,可以適當(dāng)參考。 若有問題,歡迎隨時(shí)私聊?。?! HTTP頭部信息是HTTP協(xié)議中的一部分,它包含了HTTP請求和響應(yīng)的元數(shù)據(jù)信息。HTTP頭部由一組由冒號分隔的鍵值對組成,每個(gè)鍵值對占一行,每行以回車換行

    2024年02月16日
    瀏覽(14)
  • SQL注入之HTTP頭部注入

    向服務(wù)器傳參三大基本方法:GPC GET方法,參數(shù)在URL中 POST,參數(shù)在body中 COOKIE,參數(shù)http在請求頭部中COOKIE cookie注入的注入點(diǎn)在cookie數(shù)據(jù)中,以sqil-labs-20關(guān)為例,做cookie注入練習(xí),在虛擬機(jī)中打開鏈接http://127.0.0.1/sqli-labs-master/Less-20/index.php,用戶名和密碼都輸入dumb登錄 打開火狐

    2024年02月11日
    瀏覽(19)
  • linux iptables規(guī)則修改完成后怎么立即生效

    在修改 iptables 規(guī)則后,可以使用以下命令立即生效: 使用 service iptables save 命令來保存規(guī)則,然后使用 service iptables restart 重啟 iptables 服務(wù)。 使用 /etc/init.d/iptables restart 命令重啟 iptables 服務(wù)。 注意:使用這些命令時(shí)需要 root 權(quán)限。 另外,如果想永久保存 iptables 規(guī)則,可以

    2024年02月12日
    瀏覽(16)
  • JavaWeb中Servlet+jsp+JDBC完成登錄注冊界面

    JavaWeb中Servlet+jsp+JDBC完成登錄注冊界面

    前言 一、登錄注冊思路 二、前端頁面 1.Login 2.Register 3.UserList界面 三、后端代碼 1.封裝實(shí)體類User類 2.Login對應(yīng)的Servlet(驗(yàn)證信息功能) 3.Register對應(yīng)的Servlet(增加功能) 4.工具類(DbUtil) 5.properties文件格式及所在目錄 6.用戶列表(查詢功能)? 總結(jié) 例如:學(xué)習(xí)javaweb過程筆記

    2024年02月08日
    瀏覽(22)
  • HTTP頭部信息解釋分析(詳細(xì)整理)(轉(zhuǎn)載)

    這篇文章為大家介紹了HTTP頭部信息,中英文對比分析,還是比較全面的,若大家在使用過程中遇到不了解的,可以適當(dāng)參考下 HTTP 頭部解釋 1. Accept: 告訴WEB服務(wù)器自己接受什么介質(zhì)類型, / 表示任何類型,type/* 表示該類型下的所有子類型,type/sub-type。 2. Accept-Charset: 瀏覽

    2024年02月05日
    瀏覽(16)
  • 【SQL注入漏洞-06】HTTP頭部注入靶場實(shí)戰(zhàn)

    【SQL注入漏洞-06】HTTP頭部注入靶場實(shí)戰(zhàn)

    常見的sql注入一般是 通過請求參數(shù)或者表單進(jìn)行注入 ,HTTP頭部注入是 通過HTTP協(xié)議頭部字段值進(jìn)行注入 。 產(chǎn)生HTTP頭部注入的條件: 能夠?qū)φ埱箢^消息進(jìn)行修改 修改的請求頭信息能夠帶入數(shù)據(jù)庫進(jìn)行查詢 數(shù)據(jù)庫沒有對輸入的請求信息做過濾 User-Agent :是Http協(xié)議中的一部分

    2024年02月02日
    瀏覽(26)
  • 使用jsp、HttpServlet完成一個(gè)登錄、注冊,并用MySQL連接數(shù)據(jù)進(jìn)行操作

    使用jsp、HttpServlet完成一個(gè)登錄、注冊,并用MySQL連接數(shù)據(jù)進(jìn)行操作

    這兩個(gè)是寫數(shù)據(jù)庫的軟件。 ?啟動MySQL對應(yīng)的版本型號。 user表 1.判斷存在(有沒有l(wèi)ogin的數(shù)據(jù)庫,有就刪掉)即刪除。 DROP DATABASE IF EXISTS login; 2.創(chuàng)建數(shù)據(jù)庫,使用數(shù)據(jù)庫 ?#創(chuàng)建數(shù)據(jù)庫 CREATE DATABASE login; #使用數(shù)據(jù)庫 use login; 3.創(chuàng)建一個(gè)表我們這定義叫user,給表增添3條數(shù)據(jù) #創(chuàng)

    2024年02月04日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包