Cross-Origin Resource Sharing (CORS) enables client-side Web applications downloaded from one website to retrieve data from another; including the explicit sharing of cookies and authentication information which the browser would otherwise be restricted from sending.

Before the client side code can query the Cross-Origin application server, the browser must first retrieve permission from the origin server.  Without this approval, the browser will not query the cross-origin server.   These  authorization requests can be offloaded to the NetScaler in various degrees depending on the applications servers needs and the level of security you’d like to achieve.  Here are a few example scenarios where NetScaler can assist:

  1. (Pre-Approval) NetScaler protects the app servers from DoS CORS queries by authenticating requests against a list of authorized cross-origin domains prior to forwarding to the application server.   (see example #1)     If the list of authorized domains is too large, or changes to frequently, use a combination of call-out and AppCache to maintain front-end-offloaded authorization protection without having to maintain a separate list.
  2. (Approval Offload) NetScaler offloads 100% of the authorization approvals because the application doesn’t need to customize the response. (see Example #2)
  3. (Adds Auth Header) App server sends a custom application response and NetScaler adds the authorization header for CORS protocol compliance. (see Example #3)
  4. (AppCache) NetScaler intelligently caches the server responses  to improve application performance and scale.

Example #1: Validate Cross-Domain Request

# Define authorized cross-origins
add policy patset CORS_origins_allowed
bind policy patset CORS_origins_allowed -index 1
bind policy patset CORS_origins_allowed -index 2
# Define negative response
add responder action CORS_deny_response respondwith q{"HTTP/1.0 401 Unauthorized CORS\r\n\r\n"} -bypassSafetyCheck YES
add responder policy CORS_origin_denied "HTTP.REQ.HEADER(\"Origin\").EXISTS&&HTTP.REQ.HEADER(\"Origin\").TYPECAST_HTTP_URL_T.HOSTNAME.EQUALS_ANY(\"CORS_origins_allowed\").NOT" CORS_deny_response
bind responder global CORS_origin_denied 80 END -type REQ_OVERRIDE

Sample Exchange #1

REQUEST: **************
GET /app HTTP/1.1
Accept: */*

RESPONSE: **************
HTTP/1.0 401 Unauthorized CORS

Example #2: Authorization Offload

# Define authorized cross-origins, see example #1
# Define negative response, see example #1
# Define positive response
add responder action CORS_allow_response respondwith q{"HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: "+HTTP.REQ.HEADER("Origin")+"\r\n\r\n"} -bypassSafetyCheck YES
add responder policy CORS_origin_allowed "HTTP.REQ.HEADER(\"Origin\").EXISTS&&HTTP.REQ.HEADER(\"Origin\").TYPECAST_HTTP_URL_T.HOSTNAME.EQUALS_ANY(\"CORS_origins_allowed\")" CORS_allow_response
bind responder global CORS_origin_allowed 90 END -type REQ_OVERRIDE

Sample Exchange #2

REQUEST: **************
GET /app HTTP/1.1
Accept: */*

RESPONSE: **************
HTTP/1.0 200 OK

Example #3: Insert Access-Control-Allow Header

# Create Response Rewrite Rule
add rewrite action CORS_rw-a insert_http_header Access-Control-Allow-Origin "HTTP.REQ.HEADER(\"Origin\")" -bypassSafetyCheck YES
add rewrite policy CORS_rw-p "HTTP.REQ.HEADER(\"Origin\").EXISTS&& HTTP.RES.STATUS.EQ(200)" CORS_rw-a