Add support for CORS

Description

Tutorial at http://www.html5rocks.com/en/tutorials/cors/

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true (requires .withCredentials to be set/true in the XMLHttpRequest 2 object

------

"the recommended way to do it is to have your server read the Origin header from the client, compare that to the list of domains you'd like to allow, and if it matches, echo the value of the Origin header back to the client as the Access-Control-Allow-Origin header in the response"

-> configure allowed domains in entrystore.properties

------

Advanced queries (in addition to GET and POST) require responses to preflight requests, i.e. the server has to respond to HTTP OPTIONS.

This can probably be implemented in BaseResource as this should be the same for all Resources.

------

During a CORS request, the getResponseHeader() method can only access simple response headers. Simple response headers are defined as follows:

Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma

If you want clients to be able to access other headers, you have to use the Access-Control-Expose-Headers header. The value of this header is a comma-delimited list of response headers you want to expose to the client.

Environment

None

Activity

Show:
Hannes Ebner
March 24, 2014, 4:27 PM

If the server wants to deny the CORS request, it can just return a generic response (like HTTP 200), without any CORS header. The server may want to deny the request if the HTTP method or headers requested in the preflight are not valid. Since there are no CORS-specific headers in the response, the browser assumes the request is invalid, and doesn’t make the actual request.

Hannes Ebner
March 24, 2014, 4:27 PM

3. Preflight requests

Support for this should be added to BaseResource; OPTIONS on resource has to expect the following resquest headers:

Origin: http://sub.domain.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

And should answer (if Origin is allowed according to config) with:

Access-Control-Allow-Origin: http://sub.domain.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header (echo of request)
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 10800 (time to cache permissions in seconds)

Hannes Ebner
March 24, 2014, 4:20 PM

The following needs to be implemented:

1. List of allowed origins (incl. "*") in entrystore.properties

2. CORSFilter for simple requests (HEAD, GET, POST)

In afterHandle() the filter should check for the "Origin: http://sub.domain.com" request header, compare it to the list of allowed origins, and echo it back through the following response headers:

Access-Control-Allow-Origin: http://sub.domain.com
Access-Control-Allow-Credentials: true (to allow cookies)
Access-Control-Expose-Headers: FooBar (comma-delimited, to be configured via entrystore.properties)

Simple response headers do not need to be specified:

Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma

Fixed

Assignee

Hannes Ebner

Reporter

Hannes Ebner

Labels

None

Fix versions

Priority

Normal