Forum Discussion
Rory_Hewitt_F5_
Jul 10, 2015Cirrus
Adding CORS response headers
Hey all, There are a number of other older (2013-era) threads about CORS headers, and I want to ask a specific question which has not been asked there: Can I add a response header using HTTP:...
- Oct 08, 2015
To anyone who comes in afterwards and wants to find a 'final' solution, here's what we ended up with (which functions perfectly, at least for us):
when HTTP_REQUEST priority 200 { unset cors_origin -nocomplain if { [HTTP::header Origin] ends_with ".example.com" } { if { ( [HTTP::method] equals "OPTIONS" ) and ( [HTTP::header exists "Access-Control-Request-Method"] ) } { CORS preflight request - return response immediately HTTP::respond 200 "Access-Control-Allow-Origin" [HTTP::header "Origin"] \ "Access-Control-Allow-Methods" "POST, GET, OPTIONS" \ "Access-Control-Allow-Headers" [HTTP::header "Access-Control-Request-Headers"] \ "Access-Control-Max-Age" "86400" } else { CORS GET/POST requests - set cors_origin variable set cors_origin [HTTP::header "Origin"] } } ... ... ... other irules ... ... ... } when HTTP_RESPONSE { CORS GET/POST response - check cors_origin variable set in request if { [info exists cors_origin] } { HTTP::header insert "Access-Control-Allow-Origin" $cors_origin HTTP::header insert "Access-Control-Allow-Credentials" "true" HTTP::header insert "Vary" "Origin" } }
If you have any comments about this, please do so. And, of course, feel free to use it yourself.
IheartF5_45022
Jul 27, 2015Nacreous
Hi,
We have a requirement to restrict CORS requests to domains owned by our company, or by subsidaries/partners. This rule works well for us;-
when HTTP_REQUEST {
set debug 0
set Origin ""
Can be used in prod for debugging on a per-connection basis, using a browser add-on like Firebug to add the headers
if {[HTTP::header exists "X-tls-debug"]} {
set debug 1
}
log prefix for connection/request tracking. All debug logs will start with [xxxx.yyyy] where xxxx is the connection and yyyy is the request id
if {$debug} {
per request identifier
set prefix "\[[TCP::client_port].[expr {int (rand() * 100000)}]\] "
}
if {[HTTP::header exists Origin]} {
This is a cross-origin request
if {$debug} {log local0. "${prefix} Origin:[HTTP::header Origin]"}
switch -glob -- [HTTP::header Origin] {
"*company.com" -
"*company.com.au" -
"*partner.com" -
"*partner2.com.au" {
This is a valid Origin
switch -- [HTTP::method] {
"OPTIONS" {
if {$debug} {log local0. "${prefix} Responding to Preflight request"}
HTTP::respond 200 noserver Allow "GET,HEAD,POST,OPTIONS" \
Access-Control-Allow-Origin "[HTTP::header Origin]" \
Access-Control-Allow-Methods "GET,POST" \
Access-Control-Max-Age "86400"
return
}
"GET" -
"POST" {
if {$debug} {log local0. "${prefix} Origin:[HTTP::header Origin]"}
Set variable to add headers to response
set Origin [HTTP::header Origin]
}
}
}
default {
This is a cross-origin request, however it's not from the correct domain
if {[HTTP::method] eq "OPTIONS"} {
if {$debug} {log local0. "${prefix} Responding to OPTIONS method"}
HTTP::respond 200 noserver Allow "GET,POST,HEAD,OPTIONS"
return
}
So what if it's not from correct domain, but is GET/POST - still gonna send a response, just not add in any CORS headers, which will make response fail at browser
}
}
}
}
when HTTP_RESPONSE {
if {$Origin ne ""} {
This response needs CORS headers inserted
HTTP::header insert "Access-Control-Allow-Origin" $Origin
HTTP::header insert "Access-Control-Allow-Methods" "GET,POST"
HTTP::header insert "Access-Control-Max-Age" "86400"
HTTP::header insert "Allow" "GET,HEAD,POST,OPTIONS"
}
Don't forget this - if a request is CORS-enabled, you ALWAYS need to instruct a cache to Vary a response based on Origin,
even if this particular request was not a valid cross-origin request.
HTTP::header insert "Vary" "Origin"
}
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects