Why CORS error happens even if Access-Control-Allow-Origin is present in OPTIONS response in AWS lambda trigger (API Gateway of REST API) - aws-lambda

I'm mad. Why error No 'Access-Control-Allow-Origin' header is present on the requested resource still raises even if 'Access-Control-Allow-Origin' is present in preflight response?
this is my configure:
AWS lambda function backend code (nodejs):
'use strict';
require('dotenv').config();
const mysql = require('mysql2/promise');
exports.handler = async (event, context, callback) => {
if (event.httpMethod == 'OPTIONS') {
return {
headers: {
"foo": "bar",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
statusCode: 200,
}
}
if (!event.body) {
throw new Error("no body provided")
}
const body = JSON.parse(event.body)
if (!body.statement) {
throw new Error("no statement provided")
}
const connection = await mysql.createConnection(process.env.DATABASE_URL);
const [results] = await connection.query(body.statement)
connection.end();
let response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
contentType: "application/json",
body: JSON.stringify(results)
};
return response;
};
this is the trigger configure (API Gateway of REST API)
API Gateway: planetscale-API
arn:aws:execute-api:ap-northeast-1:288496770745:832iyue4j2/*/*/planetscale
API endpoint: https://832iyue4j2.execute-api.ap-northeast-1.amazonaws.com/default/planetscale
Details
API type: REST
Authorization: NONE
Method: ANY
Resource path: /planetscale
Service principal: apigateway.amazonaws.com
Stage: default
Statement ID: lambda-11567109-822a-4850-abcf-14a1b0565c54
and this is the js code:
await axios.post("https://832iyue4j2.execute-api.ap-northeast-1.amazonaws.com/default/planetscale", { statement:"select * from t" });
this is what happend in chrome network
1.preflight request
Request URL: https://832iyue4j2.execute-api.ap-northeast-1.amazonaws.com/default/planetscale
Request Method: OPTIONS
Status Code: 200
Remote Address: 127.0.0.1:64646
Referrer Policy: strict-origin-when-cross-origin
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept
access-control-allow-methods: OPTIONS,POST,GET
access-control-allow-origin: *
content-length: 0
content-type: application/json
date: Tue, 09 Aug 2022 09:24:19 GMT
x-amz-apigw-id: WlsmmH0mNjMFZGA=
x-amzn-requestid: d25ff521-94ee-48d2-bc33-68bb92495b42
x-amzn-trace-id: Root=1-62f227c3-14547cf1741c86e83d846763;Sampled=0
xxxx: aaaa
:authority: 832iyue4j2.execute-api.ap-northeast-1.amazonaws.com
:method: OPTIONS
:path: /default/planetscale
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
access-control-request-headers: content-type
access-control-request-method: POST
origin: http://localhost:8080
referer: http://localhost:8080/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
2. POST request
Request URL: https://832iyue4j2.execute-api.ap-northeast-1.amazonaws.com/default/planetscale
Request Method: POST
Status Code: 502
Referrer Policy: strict-origin-when-cross-origin
content-length: 36
content-type: application/json
date: Tue, 09 Aug 2022 09:24:20 GMT
x-amz-apigw-id: WlsmpE_HtjMFmfw=
x-amzn-errortype: InternalServerErrorException
x-amzn-requestid: a3f991a8-1f6b-445f-b5db-697c7efaa1f8
:authority: 832iyue4j2.execute-api.ap-northeast-1.amazonaws.com
:method: POST
:path: /default/planetscale
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
content-length: 50
content-type: application/json
origin: http://localhost:8080
referer: http://localhost:8080/
sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
this is what happends in chrome console :
localhost/:1
Access to XMLHttpRequest at 'https://832iyue4j2.execute-api.ap-northeast-1.amazonaws.com/default/planetscale' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
App.vue?18cf:151 error aws lambda
xhr.js?ed5b:220
POST https://832iyue4j2.execute-api.ap-northeast-1.amazonaws.com/default/planetscale net::ERR_FAILED 502
dispatchXhrRequest # xhr.js?ed5b:220
xhrAdapter # xhr.js?ed5b:16
dispatchRequest # dispatchRequest.js?d0b9:58
request # Axios.js?3509:109
httpMethod # Axios.js?3509:144
wrap # bind.js?285c:9
Comment.query # models.js?a3ef:37
exec # modelsql.mjs?8304:626
download # App.vue?18cf:149
tryDownload # App.vue?18cf:200
invokeWithErrorHandling # vue.runtime.esm.js?3841:2988
invoker # vue.runtime.esm.js?3841:1786
original_1._wrapper # vue.runtime.esm.js?3841:7405

Related

Doesn't set cookies if domain is not localhost

i have a problem when setting the cookies other than localhost in gin gonic
c.SetCookie("token", str, 60*60*24, "/", "localhost:3000", true, true) // WORKS
c.SetCookie("token", str, 60*60*24, "/", "192.162.1.12:3000", true, true) // DOESN'T WORK
my headers are like this
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:3000", "http://192.162.1.12:3000"},
AllowMethods: []string{"POST", "OPTIONS", "GET", "PUT", "DELETE"},
AllowHeaders: []string{"Accept", "Authorization", "Content-Type", "Content-Length", "X-CSRF-Token", "Token", "session", "Origin", "Host", "Connection", "Accept-Encoding", "Accept-Language", "X-Requested-With"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
// AllowOriginFunc: func(origin string) bool {
// return origin == "https://github.com"
// },
MaxAge: 24 * time.Hour,
}))
Im calling the api from my localhost "http://192.162.1.12:3000" react page.
I do get set-cookie token but is not set in cookies.
response:
Request URL: http://localhost:5001/client-users-login
Request method: POST
Status code: 200 OK
Remote address: [::1]:5001
Referrer origin directive: strict-origin-when-cross-origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://192.168.1.10:3000
Access-Control-Expose-Headers: Content-Length
Content Length: 407
Content Type: application/json; charset = utf-8
Date: Tuesday, January 24, 2023 14:35:44 GMT
Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJicmFuY2hBZGRyZXNzIjoiYXNkYXNkc2FkIiwiYnJhbmNoSWQiOjEsImJyYW5jaE5hbWUiOiJTdWN1cnNhbCAxIiwiYnJhbmNoUGhvbmUiOiIyMzIzMjMyMyIsImNsaWVudElkIjoxLCJjbGllbnROYW1lIjoidGVzdCIsImNvbXBhbnlJZCI6MSwiZXhwIjoxNjc0NjU3MzQ0LCJnZXRTdGFydGVkIjpmYWxzZSwicm9sZUlkIjoxLCJzdGF0ZUlkIjoxLCJ1c2VyIjoidGVzdEBnbWFpbC5jb20iLCJ1c2VySWQiOiIwIn0.QhQCWMhmqcwBNVu_4EEoHdGZj0f3nUKRVCqtnUYZ8q4; path=/; Domain=192.168.1.10; Max-Age=86400; Http only; Insurance; SameSite=None
Vary: Origin
Accept: */*
Accept encoding: gzip, deflate, br
Accept-Language: es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Connection: keep alive
Content Length: 50
Content Type: application/json
Host: localhost:5001
Source: http://192.168.1.10:3000
Reference: http://192.168.1.10:3000/
sec-ch-ua: "Not_A Brand";v="99", "Microsoft Edge";v="109", "Chromium";v="109"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: between sites
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.61

esp32, esp32_https_server library, self-signed certificate, cors and 499 status code

i am working on an ESP32 project. one of my goals is to communicate with the ESP32 from a website using javascript fetch or XMLHttpRequest().
the ESP32 is connected to my local network and i am using the esp32_https_server library. it uses a self-signed certificate which the browser indicates as valid (but issues a warning, "Connection not protected" due to the self-signed certificate). the website has a CA certificate and is secure.
in testing, the esp32 is conected via USB to my computer, idealy i would like it to stand alone.
the problem i am experiencing is that i cannot seem to connect to the esp32. i keep getting status code 499 errors.
my questions are:
1) how do i successfully connect to the esp32 server from a secure website to get data frome the esp32?
2) how do i do this when the esp32 is not connected to my pc via the usb cable?
please see more info regarding the esp32 set up and responses below.
here's the esp32 code:
ResourceNode *nodeRoot = new ResourceNode("/", "GET", [](HTTPRequest *req, HTTPResponse *res) {
ResourceParameters *params = req->getParams();
std::string action = params->getRequestParameter("action");
String aksie = action.c_str();
Serial.println("Aksie: " + aksie);
if (aksie != "upload_data" && aksie != "upload_current_temp")
{
// this should be home page displayed
// Set the response status
res->setStatusCode(200);
res->setStatusText("success");
res->println("Secure Hello World!!!");
}
else
{
// either uploads..
processParams(aksie, res);
}
});
secureServer->registerNode(nodeRoot);
and here's the code that processes the "upload_current_temp" request:
if (action == "upload_current_temp")
{
// get random temperature
int currentTemp = random(0, 9);
String temp = String(currentTemp);
Serial.println("upload current temperature");
Serial.println("uploadCurrentTemp: " + temp);
std::string tem = temp.c_str();
// Set the response status
res->setStatusCode(200);
res->setStatusText("success current temperature");
StaticJsonDocument<200> doc;
doc["temperature"] = temp;
// Produce a minified JSON document
String output;
serializeJson(doc, output);
Serial.println("curent temp json output: " + output);
deserializeJson(doc, output);
// Set the content type of the response
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
// As HTTPResponse implements the Print interface, this works fine. Just remember
// to use *, as we only have a pointer to the HTTPResponse here:
serializeJson(doc, *res);
}
and also in setUp() i have this line:
secureServer->setDefaultHeader("Access-Control-Allow-Origin", "*"); //replace * with actual address
when using:
const xhr = new XMLHttpRequest();
const url = 'https://192.168.0.102/?action=upload_current_temp';
xhr.open('GET', url);
xhr.responseType = 'text';
xhr.onload = function () {
const data = xhr.response;
console.log(data);
if (this.readyState == 4 && this.status == 200) {
var obj = JSON.parse(this.responseText);
console.log("getCurTemp(), responseText: " + JSON.stringify(this.responseText, null, 2));
currentTemperature = obj.temperature;
console.log("current temperature: " + currentTemperature);
document.getElementById('currentTemp').innerHTML = currentTemperature;
}
};
xhr.send();
i get these errors (in opera):
499 (Request has been forbidden by antivirus)
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
and in chrome:
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
with these headers (opera):
Request URL: https://192.168.0.102/?action=upload_current_temp
Request Method: GET
Status Code: 499 Request has been forbidden by antivirus
Remote Address: 192.168.0.102:443
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Connection: close
Content-Length: 52266
Content-Type: text/html; charset=utf-8
Expires: Mon, 04 Dec 1999 21:29:02 GMT
Pragma: no-cache
Accept: /
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: 192.168.0.102
Origin: https://istimuli.co.uk
Referer: https://istimuli.co.uk/?code=66b72f8e-400c-4adb-ad42-f4efec391d06
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36 OPR/67.0.3575.79
action: upload_current_temp
and when using :
var url = "https://192.168.0.102/?action=upload_current_temp";
var request = new Request(url, {
method: 'GET',
mode: 'cors', // no-cors, *cors, same-origin
headers: {
'Content-Type': 'application/json'
}
});
fetch(request).then(function (response) {
// Convert to JSON
return response.json();
}).then(function (data) {
console.log("temp: " + JSON.stringify(data));
return data;
}).catch(function (error) {
console.log('Request failed', error)
return 000;
});
i get these errors in opera:
499 (Request has been forbidden by antivirus)
has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
and in chrome:
has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
and these are the headers (opera):
1 requests
51.3 KB transferred
51.0 KB resources
Request URL: https://192.168.0.102/?action=upload_current_temp
Request Method: OPTIONS
Status Code: 499 Request has been forbidden by antivirus
Remote Address: 192.168.0.102:443
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Connection: close
Content-Length: 52266
Content-Type: text/html; charset=utf-8
Expires: Mon, 04 Dec 1999 21:29:02 GMT
Pragma: no-cache
Accept: /
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: GET
Connection: keep-alive
Host: 192.168.0.102
Origin: https://istimuli.co.uk
Referer: https://istimuli.co.uk/?code=66b72f8e-400c-4adb-ad42-f4efec391d06
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36 OPR/67.0.3575.79
action: upload_current_temp

Browser auth popup not showing up in case of ajax cors with basic authentication request

From a web page of domain A, I am firing up an ajax request to domain B in order to get JSON for which basic auth is configured on domain B. I have access to the code on both the domains. I configured the all the required CORS header on domain B (Even made Access-Control-Allow-Origin header value specific and not "*", after reading some stackoverflow) What I am expecting is browser basic auth pop up, But POST request just fails with 401.I can see that server has responded with expected response header for PRE-FLIGHT OPTION request, below the request & response headers of the OPTION & actual POST method call that happens
***OPTION REQUEST***
Host: DOMAIN_B:8085
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with
Referer: http://DOMAIN_A:2280/app/
Origin: http://DOMAIN_A:2280
Connection: keep-alive
***OPTION RESPONSE***
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://DOMAIN_A:2280
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Headers: Content-Type,Authorization,x-requested-with
Access-Control-Max-Age: 1
Allow: GET,POST
Content-Type: text/html; charset=utf-8
Content-Length: 8
Date: Fri, 04 Jan 2019 12:48:48 GMT
Connection: keep-alive
*** ACTUAL POST REQUEST***
Host: DOMAIN_B:8085
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://DOMAIN_A:2280/app/
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 105
Origin: http://DOMAIN_A:2280
Connection: keep-alive
*** ACTUAL POST REQUEST***
HTTP/1.1 401 Unauthorized
X-Powered-By: Express
Vary: X-HTTP-Method-Override, Origin
Access-Control-Allow-Origin: http://DOMAIN_A:2280
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST,GET,PUT,DELETE
Access-Control-Allow-Headers: Content-Type,Authorization,x-requested-with
Access-Control-Max-Age: 1
WWW-Authenticate: Basic realm=artist
Content-Type: text/plain; charset=utf-8
Content-Length: 12
Date: Fri, 04 Jan 2019 12:48:48 GMT
Connection: keep-alive
So its expected that browser looking at the response of the POST call(401 HTTP code & WWW-Authenticate header) should get prompted to show the native authentication pop up, But it's not doing so. I am not sure what I am doing wrong here. Showing custom form to capture the credential and passing them in "Authorization" header using btoa function is not an option
Appreciate any help, I am ripping my hair apart here!!!
use basic-auth npm plugin
const auth = require('basic-auth');
app.use(function (request, response, next) {
var user = auth(request);
console.log("user => ",user);
if (!user || !user.name || !user.pass) {
response.set('WWW-Authenticate', 'Basic realm="example"');
return response.status(401).send();
}
return next();
});

Preflight request is ok, then, after auth, response does not contain allow cors header

Asp MVC 5 app deployed on IIS 8.5.
Need to enable ajax request from a number of clients.
Server-side I have In WebApiConfig.cs
config.EnableCors();
In controller:
[EnableCors(origins: "http://localhost:59901", headers: "*", methods: "*", SupportsCredentials = true)]
public class ItemController : Controller
Client side
$("#getItem").on("click", function (e) {
var myurl = "http://servername/item/details/1"
$.ajax({
url: myurl,
type: "GET",
dataType: "JSON",
xhrFields: {
withCredentials: true
},
contentType: "application/json; charset=utf-8",
error: function (jqXHR, textStatus, errorThrown) {
$('#result').text(jqXHR.responseText || textStatus);
},
success: function (result) {
$('#result').text(result);
}
});
});
Running client from VisualStudio Origin is http://localhost:59901.
Running the ajax request I get the following in fiddler:
1. Preflight request/response
OPTIONS http://vrtsrv01.webdev.local/item/details/1 HTTP/1.1
Host: vrtsrv01.webdev.local
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:59901
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: http://localhost:59901/Home/Index
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,it;q=0.6,it-IT;q=0.4
HTTP/1.1 200 OK
Server: Microsoft-IIS/8.5
Access-Control-Allow-Origin: http://localhost:59901
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, MaxDataServiceVersion
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
X-Powered-By: ASP.NET
Date: Sat, 13 May 2017 15:34:54 GMT
Content-Length: 0
2. GET request without credentials/ 401 error response
GET http://vrtsrv01.webdev.local/item/details/1 HTTP/1.1
Host: vrtsrv01.webdev.local
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:59901
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Content-Type: application/json; charset=utf-8
Referer: http://localhost:59901/Home/Index
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,it;q=0.6,it-IT;q=0.4
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Sat, 13 May 2017 15:34:54 GMT
Content-Length: 1352
Proxy-Support: Session-Based-Authentication
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Autorizzazione negata: accesso negato a causa di credenziali non valide.</title>
....
</head>
<body>
<div id="header"><h1>Errore del server</h1></div>
....
</body>
</html>
3. GET request with NTLM token for auth / response without Allow CORS header
GET http://vrtsrv01.webdev.local/item/details/1 HTTP/1.1
Host: vrtsrv01.webdev.local
Connection: keep-alive
Authorization: Negotiate <...NTLM TOKEN HERE ...>
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:59901
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Content-Type: application/json; charset=utf-8
Referer: http://localhost:59901/Home/Index
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,it;q=0.6,it-IT;q=0.4
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Sat, 13 May 2017 15:34:58 GMT
Content-Length: 8557
{"id":1, .....}
QUESTION
Why after enabling MVC app for CORS and seeing the right response to preflight request, the response obtained after NTLM authentication does not contain the expected Access-Control-Allow-Origin header?
I'm not sure that it will help you, but it might help someone else looking to have both NTLM and CORS enabled.
CORS enabling
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var corsAttr = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };
//SupportsCredentials = true means that we will add Access-Control-Allow-Credentials to the response.
config.EnableCors(corsAttr);
}
}
SupportsCredentials = true means that we will add Access-Control-Allow-Credentials to the response.
Other solutions,
global.asax.cs - properly reply with headers that allow caller from another domain to receive data
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Context.Request.HttpMethod == "OPTIONS")
{
Context.Response.AddHeader("Access-Control-Allow-Origin", Context.Request.Headers["Origin"]);
Context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,MaxDataServiceVersion");
Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
Context.Response.End();
}
}
SOLVED (...for now...)
The invoked action was a controller action returning Json. This does not work with CORS. I need to create an API controller, cannot use the existing controller. This leads to code duplication, but I have no time now to refactor the whole application to use a single controller both for MVC and API

XMLHttpRequest CROS issues when uploading(post) files to S3 from browser and redirecting to a custom url

This case is easy to understand, and I have paste enough information about the problem. Thank you for your patience. :)
There is a case that I use JQuery File Upload (UI) to upload images to AWS S3 directly from client browser, here is the post data:
AWSAccessKeyId: xxxxxx,
key: filename.jpg,
Policy: xxxxxx,
Signature: xxxxx,
acl: 'private',
success_action_redirect:'http://example.org/test',
'Content-Type': x.type
the policy and signature are totally fine, and the image has been uploaded as well.
but there is problem when redirect to the pre-defined url http://example.org/test:
XMLHttpRequest cannot load https://s3-eu-west-1.amazonaws.com/mybucket/.
The request was redirected to 'http://localhost:8000/test?bucket=mybucket&key=filename.jpg&etag=xxxxxxxx',
which is disallowed for cross-origin requests that require preflight.
I paste the http request and response for https://s3-eu-west-1.amazonaws.com/mybucket/:
Request:
POST /mybucket/ HTTP/1.1
Host: s3-eu-west-1.amazonaws.com
Connection: keep-alive
Content-Length: 298856
Origin: http://localhost:8000
X-CSRF-TOKEN: H5HRwmtwCVAxIgmAvM8YL5bgayuDyyQV2UKUqnhT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhI9Z5605GrykYXvT
Accept: application/json, text/javascript, */*; q=0.01
Content-Disposition: attachment; filename="xxxxxxx"
Referer: http://localhost:8000/xxxxxxxx
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Response:
HTTP/1.1 303 See Other
x-amz-id-2: g1VdA6dwEHl+y/C8nSTD7qzxL7gX9o3c0JV7Cj7cKYDeUPNvlrkRzaJEz4PtNFCPZhOAhA8pqzw=
x-amz-request-id: 48C7F5DB54CCEF65
Date: Thu, 29 Oct 2015 02:35:31 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
ETag: "772d776abbc1bb619d208c92d4b986c9"
Location: http://localhost:8000/test?bucket=mybucket&key=filename.jpg&etag=xxxxxxxx
Content-Length: 0
Server: AmazonS3
And for the redirect endpoint http://example.org/test, which is implemented in Laravel 5.1. Here are the relative routes:
Route::group(['prefix' => 'test'], function () {
Route::options('/', function(){
return response(null, 204)
->header('Access-Control-Allow-Origin' , '*')
->header('Access-Control-Allow-Credentials', 'true')
->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
->header('Access-Control-Allow-Headers', 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type')
->header('Access-Control-Max-Age', '1728000')
->header('Content-Type', 'text/plain charset=UTF-8')
->header('Content-Length', '0');
});
Route::get('/', function () {
return response('test', 200)
->header('Access-Control-Allow-Origin' , '*')
->header('Access-Control-Allow-Credentials', 'true')
->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
->header('Access-Control-Allow-Headers', 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type');
});
});
When GET http://example.org/test directly, here is the HTTP response headers:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type
Access-Control-Allow-Methods:POST, GET, OPTIONS
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Connection:close
Content-Type:text/html; charset=UTF-8
Date:Thu, 29 Oct 2015 02:47:51 GMT
Host:localhost:8000
Any body can help me figure out where is the problem? Thanks!

Resources