Tomcat CORS:预检成功,但实际请求因 403 禁止而失败
Tomcat CORS: Preflight successful, but actual request fails with 403 forbidden
我的 REST 服务部署在 Tomcat 7.0.64 (http://localhost:8080/xxx). I invoke these services from using a JavaScript library sourced by HTML pages. These HTML pages are served from another orgin (http://localhost:9090/html/yyy.html) 下。
为了启用跨源请求,在服务器上,我在 web.xml 中配置了 CORSFilter,如下所示:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-CUSTOM1,X-CUSOM2,X-CUSTOM3</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,X-CUSTOM3</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
从 RequestDumper 的输出中,您可以注意到来自浏览器的预检请求已收到成功响应(200)。但是,随后的实际请求因 403 Forbidden:
而失败
预检请求和响应
http-apr-8080-exec-6 ===============================================================
http-apr-8080-exec-8 START TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-8 requestURI=/xxxx/zzzz
http-apr-8080-exec-8 authType=null
http-apr-8080-exec-8 characterEncoding=null
http-apr-8080-exec-8 contentLength=-1
http-apr-8080-exec-8 contentType=null
http-apr-8080-exec-8 contextPath=/xxxx
http-apr-8080-exec-8 header=host=localhost:8080
http-apr-8080-exec-8 header=connection=keep-alive
http-apr-8080-exec-8 header=pragma=no-cache
http-apr-8080-exec-8 header=cache-control=no-cache
http-apr-8080-exec-8 header=access-control-request-method=POST
http-apr-8080-exec-8 header=origin=http://localhost:9090
http-apr-8080-exec-8 header=user-agent=Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36
http-apr-8080-exec-8 header=access-control-request-headers=x-custom1, x-custom2
http-apr-8080-exec-8 header=accept=*/*
http-apr-8080-exec-8 header=referer=http://localhost:9090/html/yyyy.html
http-apr-8080-exec-8 header=accept-encoding=gzip, deflate, sdch
http-apr-8080-exec-8 header=accept-language=en-US,en;q=0.8,ta;q=0.6
http-apr-8080-exec-8 locale=en_US
http-apr-8080-exec-8 method=OPTIONS
http-apr-8080-exec-8 pathInfo=null
http-apr-8080-exec-8 protocol=HTTP/1.1
http-apr-8080-exec-8 queryString=null
http-apr-8080-exec-8 remoteAddr=127.0.0.1
http-apr-8080-exec-8 remoteHost=127.0.0.1
http-apr-8080-exec-8 remoteUser=null
http-apr-8080-exec-8 requestedSessionId=null
http-apr-8080-exec-8 scheme=http
http-apr-8080-exec-8 serverName=localhost
http-apr-8080-exec-8 serverPort=8080
http-apr-8080-exec-8 servletPath=/zzzz
http-apr-8080-exec-8 isSecure=false
http-apr-8080-exec-8 ------------------=--------------------------------------------
http-apr-8080-exec-8 ------------------=--------------------------------------------
http-apr-8080-exec-8 authType=null
http-apr-8080-exec-8 contentType=null
http-apr-8080-exec-8 header=Access-Control-Allow-Origin=http://localhost:9090
http-apr-8080-exec-8 header=Access-Control-Allow-Credentials=true
http-apr-8080-exec-8 header=Access-Control-Max-Age=10
http-apr-8080-exec-8 header=Access-Control-Allow-Methods=POST
http-apr-8080-exec-8 header=Access-Control-Allow-Headers=content-type,x-custom1,access-control-request-headers,accept,access-control-request-method,x-custom2,origin,x-custom3,x-requested-with
http-apr-8080-exec-8 remoteUser=null
http-apr-8080-exec-8 status=200
http-apr-8080-exec-8 END TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-8 ===============================================================
实际请求和响应 - 因 403 Forbidden
而失败
http-apr-8080-exec-9 START TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-9 requestURI=/xxxx/zzzz
http-apr-8080-exec-9 authType=null
http-apr-8080-exec-9 characterEncoding=null
http-apr-8080-exec-9 contentLength=0
http-apr-8080-exec-9 contentType=null
http-apr-8080-exec-9 contextPath=/xxxx
http-apr-8080-exec-9 header=host=localhost:8080
http-apr-8080-exec-9 header=connection=keep-alive
http-apr-8080-exec-9 header=content-length=0
http-apr-8080-exec-9 header=pragma=no-cache
http-apr-8080-exec-9 header=cache-control=no-cache
http-apr-8080-exec-9 header=origin=http://localhost:9090
http-apr-8080-exec-9 header=x-custom1=aaaaa
http-apr-8080-exec-9 header=x-custom2=bbbbb
http-apr-8080-exec-9 header=user-agent=Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36
http-apr-8080-exec-9 header=accept=*/*
http-apr-8080-exec-9 header=referer=http://localhost:9090/html/yyyy.html
http-apr-8080-exec-9 header=accept-encoding=gzip, deflate
http-apr-8080-exec-9 header=accept-language=en-US,en;q=0.8,ta;q=0.6
http-apr-8080-exec-9 locale=en_US
http-apr-8080-exec-9 method=POST
http-apr-8080-exec-9 pathInfo=null
http-apr-8080-exec-9 protocol=HTTP/1.1
http-apr-8080-exec-9 queryString=null
http-apr-8080-exec-9 remoteAddr=127.0.0.1
http-apr-8080-exec-9 remoteHost=127.0.0.1
http-apr-8080-exec-9 remoteUser=null
http-apr-8080-exec-9 requestedSessionId=null
http-apr-8080-exec-9 scheme=http
http-apr-8080-exec-9 serverName=localhost
http-apr-8080-exec-9 serverPort=8080
http-apr-8080-exec-9 servletPath=/zzzz
http-apr-8080-exec-9 isSecure=false
http-apr-8080-exec-9 ------------------=--------------------------------------------
http-apr-8080-exec-9 ------------------=--------------------------------------------
http-apr-8080-exec-9 authType=null
http-apr-8080-exec-9 contentType=text/plain
http-apr-8080-exec-9 remoteUser=null
http-apr-8080-exec-9 status=403
http-apr-8080-exec-9 END TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-9 ===============================================================
我正在使用 Chrome 作为我的浏览器。
我想知道,当预检请求成功时,实际响应是否有可能得到 403 forbidden?
Also please note that I have tested sending this same request from
Chrome plugin Postman and I could get the expected response
successfully without 403 error.
我完成了 Tomcat CORSFilter flowchart 中给出的流程。我不清楚这里出了什么问题。感谢您帮助解决问题。谢谢。
我遇到了完全相同的问题。解决方法其实很简单。
"There I noticed that the HTTP POST requests are somehow required to have the Content-Type HTTP header filled."
尝试向您的 POST 请求添加内容类型。
要添加到 ,这在 Postman 中起作用但在浏览器本身中不起作用的最可能原因是 Postman 可能会自动将 Content-Type
添加到请求中。
我的 REST 服务部署在 Tomcat 7.0.64 (http://localhost:8080/xxx). I invoke these services from using a JavaScript library sourced by HTML pages. These HTML pages are served from another orgin (http://localhost:9090/html/yyy.html) 下。
为了启用跨源请求,在服务器上,我在 web.xml 中配置了 CORSFilter,如下所示:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-CUSTOM1,X-CUSOM2,X-CUSTOM3</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,X-CUSTOM3</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
从 RequestDumper 的输出中,您可以注意到来自浏览器的预检请求已收到成功响应(200)。但是,随后的实际请求因 403 Forbidden:
而失败预检请求和响应
http-apr-8080-exec-6 ===============================================================
http-apr-8080-exec-8 START TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-8 requestURI=/xxxx/zzzz
http-apr-8080-exec-8 authType=null
http-apr-8080-exec-8 characterEncoding=null
http-apr-8080-exec-8 contentLength=-1
http-apr-8080-exec-8 contentType=null
http-apr-8080-exec-8 contextPath=/xxxx
http-apr-8080-exec-8 header=host=localhost:8080
http-apr-8080-exec-8 header=connection=keep-alive
http-apr-8080-exec-8 header=pragma=no-cache
http-apr-8080-exec-8 header=cache-control=no-cache
http-apr-8080-exec-8 header=access-control-request-method=POST
http-apr-8080-exec-8 header=origin=http://localhost:9090
http-apr-8080-exec-8 header=user-agent=Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36
http-apr-8080-exec-8 header=access-control-request-headers=x-custom1, x-custom2
http-apr-8080-exec-8 header=accept=*/*
http-apr-8080-exec-8 header=referer=http://localhost:9090/html/yyyy.html
http-apr-8080-exec-8 header=accept-encoding=gzip, deflate, sdch
http-apr-8080-exec-8 header=accept-language=en-US,en;q=0.8,ta;q=0.6
http-apr-8080-exec-8 locale=en_US
http-apr-8080-exec-8 method=OPTIONS
http-apr-8080-exec-8 pathInfo=null
http-apr-8080-exec-8 protocol=HTTP/1.1
http-apr-8080-exec-8 queryString=null
http-apr-8080-exec-8 remoteAddr=127.0.0.1
http-apr-8080-exec-8 remoteHost=127.0.0.1
http-apr-8080-exec-8 remoteUser=null
http-apr-8080-exec-8 requestedSessionId=null
http-apr-8080-exec-8 scheme=http
http-apr-8080-exec-8 serverName=localhost
http-apr-8080-exec-8 serverPort=8080
http-apr-8080-exec-8 servletPath=/zzzz
http-apr-8080-exec-8 isSecure=false
http-apr-8080-exec-8 ------------------=--------------------------------------------
http-apr-8080-exec-8 ------------------=--------------------------------------------
http-apr-8080-exec-8 authType=null
http-apr-8080-exec-8 contentType=null
http-apr-8080-exec-8 header=Access-Control-Allow-Origin=http://localhost:9090
http-apr-8080-exec-8 header=Access-Control-Allow-Credentials=true
http-apr-8080-exec-8 header=Access-Control-Max-Age=10
http-apr-8080-exec-8 header=Access-Control-Allow-Methods=POST
http-apr-8080-exec-8 header=Access-Control-Allow-Headers=content-type,x-custom1,access-control-request-headers,accept,access-control-request-method,x-custom2,origin,x-custom3,x-requested-with
http-apr-8080-exec-8 remoteUser=null
http-apr-8080-exec-8 status=200
http-apr-8080-exec-8 END TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-8 ===============================================================
实际请求和响应 - 因 403 Forbidden
而失败http-apr-8080-exec-9 START TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-9 requestURI=/xxxx/zzzz
http-apr-8080-exec-9 authType=null
http-apr-8080-exec-9 characterEncoding=null
http-apr-8080-exec-9 contentLength=0
http-apr-8080-exec-9 contentType=null
http-apr-8080-exec-9 contextPath=/xxxx
http-apr-8080-exec-9 header=host=localhost:8080
http-apr-8080-exec-9 header=connection=keep-alive
http-apr-8080-exec-9 header=content-length=0
http-apr-8080-exec-9 header=pragma=no-cache
http-apr-8080-exec-9 header=cache-control=no-cache
http-apr-8080-exec-9 header=origin=http://localhost:9090
http-apr-8080-exec-9 header=x-custom1=aaaaa
http-apr-8080-exec-9 header=x-custom2=bbbbb
http-apr-8080-exec-9 header=user-agent=Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36
http-apr-8080-exec-9 header=accept=*/*
http-apr-8080-exec-9 header=referer=http://localhost:9090/html/yyyy.html
http-apr-8080-exec-9 header=accept-encoding=gzip, deflate
http-apr-8080-exec-9 header=accept-language=en-US,en;q=0.8,ta;q=0.6
http-apr-8080-exec-9 locale=en_US
http-apr-8080-exec-9 method=POST
http-apr-8080-exec-9 pathInfo=null
http-apr-8080-exec-9 protocol=HTTP/1.1
http-apr-8080-exec-9 queryString=null
http-apr-8080-exec-9 remoteAddr=127.0.0.1
http-apr-8080-exec-9 remoteHost=127.0.0.1
http-apr-8080-exec-9 remoteUser=null
http-apr-8080-exec-9 requestedSessionId=null
http-apr-8080-exec-9 scheme=http
http-apr-8080-exec-9 serverName=localhost
http-apr-8080-exec-9 serverPort=8080
http-apr-8080-exec-9 servletPath=/zzzz
http-apr-8080-exec-9 isSecure=false
http-apr-8080-exec-9 ------------------=--------------------------------------------
http-apr-8080-exec-9 ------------------=--------------------------------------------
http-apr-8080-exec-9 authType=null
http-apr-8080-exec-9 contentType=text/plain
http-apr-8080-exec-9 remoteUser=null
http-apr-8080-exec-9 status=403
http-apr-8080-exec-9 END TIME =26-Sep-2015 21:28:53
http-apr-8080-exec-9 ===============================================================
我正在使用 Chrome 作为我的浏览器。
我想知道,当预检请求成功时,实际响应是否有可能得到 403 forbidden?
Also please note that I have tested sending this same request from Chrome plugin Postman and I could get the expected response successfully without 403 error.
我完成了 Tomcat CORSFilter flowchart 中给出的流程。我不清楚这里出了什么问题。感谢您帮助解决问题。谢谢。
我遇到了完全相同的问题。解决方法其实很简单。
"There I noticed that the HTTP POST requests are somehow required to have the Content-Type HTTP header filled."
尝试向您的 POST 请求添加内容类型。
要添加到 Content-Type
添加到请求中。