Cross-origin Resource Sharing (CORS) allows a script running in another domain to access a Caché REST service. Typically, when a browser is running a script from one domain, it allows XMLHttpRequest calls to that same domain but disallows them when they are made to another domain. This browser behavior restricts someone from creating a malicious script that can misuse confidential data. The malicious script could allow the user to access information in another domain using permissions granted to the user, but then, unknown to the user, make other use of confidential information. To avoid this security problem, browsers generally do not allow this kind of cross-domain call.
Without using CORS, a web page with a script accessing REST services typically must be in the same domain as the server providing the REST services. In some environments, it is useful to have the web pages with scripts in a different domain than the servers providing the REST services. CORS enables this arrangement.
The following provides a simplified description of how a browser can handle an XMLHttpRequest with CORS:
A script in a web page in domain DomOne contains an XMLHttpRequest to a Caché REST service that is in domain DomTwo. The XMLHttpRequest has a custom header for CORS.
A user views this web page and runs the script. The user’s browser detects the XMLHttpRequest to a domain different from the one containing the web page.
The user’s browser sends a special request to the Caché REST service that indicates the HTTP request method of the XMLHttpRequest and the domain of the originating web page, which is DomOne in this example.
If the request is allowed, the response contains the requested information. Otherwise, the response consists only of headers indicating that CORS did not allow the request.
Caché supports CORS by passing the HTTP headers and allows you to configure whether a REST service allows the CORS header. You must write code that defines when to allow a CORS request. For example, you can provide a white-list containing domains that contain only trusted scripts. Caché does provides a simple default implementation for documentation purposes but it allows any CORS request. You should not enable CORS processing for confidential data using this default implementation.
This chapter contains the following sections:
Configuring a REST Service to Use CORS
If CORS processing is disabled for an incoming REST URL with CORS headers, %CSP.REST
rejects the incoming request.
Overriding the OnHandleCorsRequest Method
The default implementation of the OnHandleCorsRequest()
method does not do any filtering and simply passes the CORS header to the external server and returns the response. You may want to restrict access to origins that are listed in a domain white list or to restrict what request methods are allowed. You do this by overriding the OnHandleCorsRequest()
method in your %CSP.REST
To implement the OnHandleCorsRequest()
method, you must be familiar with the details of the CORS protocol. This section identifies the parts of the default OnHandleCorsRequest()
method implementation and identifies the lines that handle the origin, credentials, header, and request method.
The following code from the %CSP.REST.HandleDefaultCorsRequest()
method gets the origin and use it to set the response header. One possible way to handle this is to test the origin against a white list and only use it to set the response header if the domain is allowed. If it is not allowed, you can set the response header to an empty string.
#; Get the origin
#; Allow requested origin
The following lines specify that the authorization header should be included.
#; Set allow credentials to be true
The following lines get the headers and the request method from the incoming request. Add code to test if these headers and request method are allowed. If they are allowed, use them to set the response headers.
#; Allow requested headers
#; Allow requested method
method provides a simple default implementation for documentation purposes only. You should not enable CORS processing for confidential data using this default implementation.