Accessing WFS resources from a Web Browser

Modern web applications typically retrieve data using the browser’s XMLHttpRequest API. This technique is commonly known as Ajax. It allows developers to download data to the browser without reloading the web page.

Ajax-powered applications are subject to strict security policies: XMLHttpRequest instances are subject to the web browser’s same origin policy. Only requests made to the server that served the original web page are permitted. More specifically, if a web application wants to access WFS resources, the WFS servlet must be hosted on the same server that hosts the web application. This limitation severely limits deployment options for WFS services in a RIA context.

Several solutions exist to address the same-origin policy:

Proxy service

The server that hosts the RIA application also hosts a proxy service that the RIA application can use to retrieve data. The proxy forwards the request to the appropriate server.

JSONP

JSON with Padding (JSONP) exploits the browser’s policy that <script> tags in a web application are not subject to the same origin policy. By dynamically adding <script> tags in the web page, JSONP allows arbitrary data to be downloaded to the application. Due to the nature of the solution, the JSONP approach is limited to HTTP GET requests.

CORS

CORS, or Cross Origin Resource Sharing, is a W3C Working Draft that allows a developer to direct an XMLHttpRequest at another server if the request adheres to that server’s security policy.

The Luciad WFS distribution includes a general purpose library that implements the server side responsibilities of the CORS protocol. The following section describes how you can configure the Luciad WFS servlet with the CORS protocol.

Each cross-origin solution comes with its benefits and disadvantages, which are beyond the scope of this document. Before you select a solution, evaluate which solution best fits your needs. Although the Luciad WFS distribution includes a configurable CORS implementation, applying it may not be in line with the security policy of your deployment environment.

Configuring Cross Origin Resource Sharing

The Luciad WFS distribution includes an implementation of the CORS protocol realized as a servlet filter. Adding and removing CORS support is as simple as adding a filter section to or removing it from the deployment descriptor of the WFS servlet. See Configuration of the deployment descriptor for more information.

The definition of the filter in the <filter> section, and its application on the WFS servlet in the <filter-mapping> section is shown in Program: CORS filter specification.

Program: CORS filter specification
<filter>
  <filter-name>CORSFilter</filter-name>
  <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>CORSFilter</filter-name>
  <servlet-name>wfs</servlet-name>
</filter-mapping>

After applying the CORS filter to the WFS server, you are encouraged to configure the filter to fit your security needs. The following servlet filter parameters are supported:

cors.allowGenericHttpRequests

  • Possible values: true|false

  • Default value: true

  • Description: if true, generic HTTP requests are allowed to pass the filter. Otherwise, only valid and accepted CORS requests will be allowed. This is also known as strict CORS filtering. This parameter should generally be set to true, unless the WFS server is to serve cross origin requests exclusively.

cors.allowOrigin

  • Possible values: “*” | origin-list

  • Default value: “*”

  • Description: whitespace-separated list of origins that the CORS filter must allow. Requests from origins not included here will be refused with an HTTP 403 Forbidden response. If the parameter is set to *, any origin will be allowed.

cors.supportedMethods

  • Possible values: HTTP methods

  • Default value: GET, POST, HEAD, OPTIONS

  • Description: list of the supported HTTP methods. These are advertised through the Access-Control-Allow-Methods header and must also be implemented by the actual CORS web service. Requests for methods not included here will be refused by the CORS filter with an HTTP 405 Method not allowed response.

cors.supportedHeaders

  • Possible values: header list

  • Default value: <empty>

  • Description: the names of the supported author request headers. These are advertised through the Access-Control-Allow-Headers. An author request header is any custom header set by the browser JavaScript application through the XMLHttpRequest.setRequestHeader() method.

cors.exposedHeaders

  • Possible values: header list

  • Default value: <empty>

  • Description: list of the response headers other than simple response headers that the browser should expose to the author of the cross-domain request through the XMLHttpRequest.getResponseHeader() method. the CORS filter supplies this information through the Access-Control-Expose-Headers header.

cors.supportsCredentials

  • Possible values: true|false

  • Default value: true

  • Description: indicates whether user credentials, such as cookies, HTTP authentication or client-side certificates are supported. The CORS filter uses this value in the Access-Control-Allow-Credentials header.

cors.maxAge

  • Possible values: int

  • Default value: -1

  • Description: indicates in seconds how long the results of a pre-flight request can be cached by the web browser. This information is passed to the browser via the Access-Control-Max-Age header. If the value is -1, the header will not be specified.