1

I try to solve the error 403 Forbidden that I get when sending requests to my GeoServer. To debug the process, I use Network tab from Inspect option in Chrome (I also tried Firefox). This is the error that I see in the Network tab.

XMLHttpRequest cannot load http://localhost:8080/geoserver/square/ows?service=WFS&version=1.1.0&requ…ture&typeName=square:InformationStores&outputFormat=application%2Fjson. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5601' is therefore not allowed access. The response had HTTP status code 403.

My GeoServer 2.10.4 is CORS enabled according to multiple tutorials that I found on this topic. However, the error message that I receive seems to be related to proxy.

I spent so much time trying to solve this issue, so finally, I am absolutely lost. I tried a lot of things, but nothing has worked.

This is the configuration file of GeoServer to which I send request:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app>
    <display-name>GeoServer</display-name>

      <context-param>
    <param-name>serviceStrategy</param-name>
    <!-- Meaning of the different values :

         PARTIAL-BUFFER2
         - Partially buffers the first xKb to disk. Once that has buffered, the the 
           result is streamed to the user. This will allow for most errors to be caught
           early. 

         BUFFER
         - stores the entire response in memory first, before sending it off to
           the user (may run out of memory)

         SPEED
         - outputs directly to the response (and cannot recover in the case of an
           error)

         FILE
         - outputs to the local filesystem first, before sending it off to the user
      -->
    <param-value>PARTIAL-BUFFER2</param-value>   </context-param>
     <context-param>
    <!-- see comments on the PARTIAL-BUFFER strategy -->
    <!-- this sets the size of the buffer.  default is "50" = 50kb -->

    <param-name>PARTIAL_BUFFER_STRATEGY_SIZE</param-name>
    <param-value>50</param-value>   </context-param>
     <!--Can be true or false (defaults to: false). -->   <!--When true the JSONP (text/javascript) output format is enabled -->   <!--   <context-param>
    <param-name>ENABLE_JSONP</param-name>
    <param-value>true</param-value>   </context-param>   -->
    <!-- 
    <context-param>
      <param-name>PROXY_BASE_URL</param-name>
      <param-value>http://localhost/geoserver</param-value>
    </context-param>
     -->

     <!--
    <context-param>
       <param-name>GEOSERVER_DATA_DIR</param-name>
        <param-value>C:\eclipse\workspace\geoserver_trunk\cite\confCiteWFSPostGIS</param-value>
    </context-param>     -->

    <!-- pick up all spring application contexts -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/applicationContext.xml classpath*:/applicationSecurityContext.xml</param-value>
    </context-param>

    <filter>
     <filter-name>FlushSafeFilter</filter-name>
     <filter-class>org.geoserver.filters.FlushSafeFilter</filter-class>
    </filter>

    <filter>
      <filter-name>Set Character Encoding</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
      </init-param>
    </filter>

    <filter>
     <filter-name>SessionDebugger</filter-name>
     <filter-class>org.geoserver.filters.SessionDebugFilter</filter-class>
    </filter>

    <filter>
    <filter-name>filterChainProxy</filter-name>     
     <filter-class> org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter>
      <filter-name>xFrameOptionsFilter</filter-name>
      <filter-class>org.geoserver.filters.XFrameOptionsFilter</filter-class>
    </filter>

   <filter>
     <filter-name>GZIP Compression Filter</filter-name>
     <filter-class>org.geoserver.filters.GZIPFilter</filter-class>
     <init-param>
         <!-- The compressed-types parameter is a comma-separated list of regular expressions.
              If a mime type matches any of the regular expressions then it will be compressed.
              -->
         <param-name>compressed-types</param-name>
         <param-value>text/.*,.*xml.*,application/json,application/x-javascript</param-value>
     </init-param>    </filter>

   <filter>
     <filter-name>Request Logging Filter</filter-name>
     <filter-class>org.geoserver.filters.LoggingFilter</filter-class>
     <init-param>
         <!-- The 'enabled' parameter is a boolean value, "true" (case-insensitive) for true or
              any other value for false.  If enabled, then the logging will be performed;
              otherwise the logging filter will have no effect.  If not specified, this 
              parameter defaults to false.
              -->
         <param-name>enabled</param-name>
         <param-value>false</param-value>
     </init-param>
     <init-param>
     <!-- The 'log-request-bodies' parameter is a boolean value, "true" (case-insensitive) for
          true or any other value for false.  If enabled, then the logging will include the body
          of POST and PUT requests.  If not specified, this parameter defaults to false.
          Note that this may noticeably degrade responsiveness of your geoserver since it will
          not begin to process requests until the entire request body has been received by the 
          server.
          -->
     <param-name>log-request-bodies</param-name>
     <param-value>false</param-value>
     </init-param>    </filter>
       <filter>
     <filter-name>Advanced Dispatch Filter</filter-name>
     <filter-class>org.geoserver.platform.AdvancedDispatchFilter</filter-class>
     <!-- 
     This filter allows for a single mapping to the spring dispatcher. However using /* as a mapping
     in a servlet mapping causes the servlet path to be "/" of the request. This causes problems with
     library like wicket and restlet. So this filter fakes the servlet path by assuming the first 
     component of the path is the mapped path. 
     -->    </filter>
       <filter>
    <filter-name>Spring Delegating Filter</filter-name>
    <filter-class>org.geoserver.filters.SpringDelegatingFilter</filter-class>
    <!--
    This filter allows for filters to be loaded via spring rather than 
    registered here in web.xml.  One thing to note is that for such filters 
    init() is not called. INstead any initialization is performed via spring 
    ioc.
    -->    </filter>
       <filter>
     <filter-name>Thread locals cleanup filter</filter-name>
     <filter-class>org.geoserver.filters.ThreadLocalsCleanupFilter</filter-class>
     <!-- 
     This filter cleans up thread locals Geotools is setting up for concurrency and performance
     reasons 
     -->    </filter>    <!-- Uncomment following filter to enable CORS -->    <filter>
        <filter-name>cross-origin</filter-name>
        <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
    </filter>

    <!-- 
      THIS FILTER MUST BE THE FIRST ONE, otherwise we end up with ruined chars in the input from the GUI
      See the "Note" in the Tomcat character encoding guide:
      http://wiki.apache.org/tomcat/FAQ/CharacterEncoding
    -->
    <filter-mapping>
      <filter-name>Set Character Encoding</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
       <!-- Uncomment following filter to enable CORS -->
    <filter-mapping>
        <filter-name>cross-origin</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

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

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

    <filter-mapping>
      <filter-name>GZIP Compression Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

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

    <filter-mapping>
      <filter-name>Request Logging Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 
      If you want to use your security system comment out this one too
    -->
    <filter-mapping>
      <filter-name>filterChainProxy</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
      <filter-name>Advanced Dispatch Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
      <filter-name>Spring Delegating Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
      <filter-name>Thread locals cleanup filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- general initializer, should be first thing to execute -->
    <listener>
      <listener-class>org.geoserver.GeoserverInitStartupListener</listener-class>
    </listener>

    <!-- logging initializer, should execute before spring context startup -->
    <listener>
      <listener-class>org.geoserver.logging.LoggingStartupContextListener</listener-class>
    </listener>

    <!--  spring context loader -->
    <listener>
      <listener-class>org.geoserver.platform.GeoServerContextLoaderListener</listener-class>
    </listener>

    <!--  http session listener proxy -->
    <listener>
      <listener-class>org.geoserver.platform.GeoServerHttpSessionListenerProxy</listener-class>
    </listener>

    <!-- request context listener for session-scoped beans -->  <listener>      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>     </listener>

    <!-- spring dispatcher servlet, dispatches all incoming requests -->
    <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>

    <!-- single mapping to spring, this only works properly if the advanced dispatch filter is 
         active -->
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <mime-mapping>
      <extension>xsl</extension>
      <mime-type>text/xml</mime-type>
    </mime-mapping>
    <mime-mapping>
      <extension>sld</extension>
      <mime-type>text/xml</mime-type>
    </mime-mapping>
    <mime-mapping>
      <extension>json</extension>
      <mime-type>application/json</mime-type>
    </mime-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
     </web-app>
Dinosaurius
  • 8,306
  • 19
  • 64
  • 113
  • Please check this out, I believe you have same issue https://gis.stackexchange.com/questions/210316/access-control-allow-origin-openlayers-wfs – 2oppin Jul 29 '17 at 07:38
  • @2oppin: Thank you, but this is exactly what I did (many times!). So, I added ` cross-origin org.eclipse.jetty.servlets.CrossOriginFilter cross-origin /* ` into `web.xml` of GeoServer and I putted the appropriate version of jetty jar into `WEB-INF/lib`. – Dinosaurius Jul 29 '17 at 07:42
  • I'm not aware of geoServer, but I suppose it may be setup over some other http server. Do you use jetty for it? I suppose depending on server apache/tomcat/ jetty they all use their own filters, If you have some custom server built with spring then you should add header manually – 2oppin Jul 29 '17 at 07:58
  • @2oppin: Yes, I use Jetty. Basically I have GeoServer (server side) and Kibana (client side). That's it. GeoServer is located on port `8080`, while Kibana is running on port `5601`. Both are on the same domain (well, now it's just localhost). I do not have any custom server. In particular, `Remote Address:127.0.0.1:8080 Host:localhost:8080 Origin:http://localhost:5601 Referer:http://localhost:5601/app/kibana` – Dinosaurius Jul 29 '17 at 08:02
  • Try to use newest Jetty version, https://www.eclipse.org/jetty/documentation/9.4.x/cross-origin-filter.html Try to add headers in init params like in this question https://stackoverflow.com/questions/8303162/jetty-cross-origin-filter – 2oppin Jul 29 '17 at 13:15
  • @2oppin: I made exactly the same. Still getting the same error. I think it's related to proxy settings. Do you know how to specify that `localhost:8080` can be accessed from `localhost:5601`? – Dinosaurius Jul 30 '17 at 10:57
  • @2oppin: I also tried to use "Allow-Control-Allow-Origin" plugin for Chrome, but still get `Response for preflight has invalid HTTP status code 403` – Dinosaurius Jul 30 '17 at 11:23
  • Have you set allowedOrigins * ? If so, I run out of ideas. As for proxy, I went sometimes with apache proxy by redirecting requests in some mysite.local 127.0.0.1 written in the hosts Ex: https://stackoverflow.com/questions/21441227/apache-using-reverse-proxy-and-run-local-website – 2oppin Jul 30 '17 at 12:27
  • btw, If you'll go with apache, maybe you'll have more luck with tomcat http://docs.geoserver.org/latest/en/user/installation/war.html#installation-war – 2oppin Jul 30 '17 at 12:35
  • @2oppin: Yes, I set ` allowedOrigins * `. No effect. So, I will switch to Tomcat, because I have tried so many things and nothing worked. – Dinosaurius Jul 30 '17 at 12:44
  • @2oppin: It worked with Apache Tomcat 7 and catalina filters (not jetty) – Dinosaurius Jul 30 '17 at 15:34
  • duplicate of https://gis.stackexchange.com/questions/210109/enabling-cors-in-geoserver-jetty – Ian Turton Jul 31 '17 at 08:05

1 Answers1

0

Please see my answer to this question.

Instead of adding to the web.xml, simply uncomment the two CORS related blocks that are already in there.

Ian Turton
  • 10,018
  • 1
  • 28
  • 47