Cross-origin resource sharing error: PreflightInvalidstatus in Azure Application API - azure

I have backend Springboot API service which is running behind the Azure Application Gateway. The APIs are getting used in a Single page application. Spring boot APIs are well configured for CORS and working prefectly fine in ideal scenarios.
But getting CORS errror when Beackendend service is not responsive/down. I setup these values in Application gateway to deal with Preflight calls in case java service is not reachable.
Access-Control-Allow-Origin: {http_req_Origin}
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Headers: x-requested-with, authorization, content-type, unique-one-time-token
Access-Control-Max-Age: 1800
After doing these rewrite rules , there is still CORS error Cross-origin resource sharing error: PreflightInvalidstatus

See if any of the below can be workaround in your case
Make sure the request URL in your code isn’t missing a trailing
slash.
for example, you may need to add a trailing slash in your
code— e.g., http://localhost/api/auth/login/  or remove the slash
if present http://localhost/api/auth/login and try.
This may even happen sometimes when you try calling an https service as http, for example when you perform a request on :'http:// localhost/api/auth/login ' which might have to be be 'https:// localhost/api/auth/login
Or
You need to reply to that CORS preflight with the appropriate CORS
headers to make this work.
A CORS-preflight request is a CORS request that checks to see if
the CORS protocol is understood. It uses OPTIONS
as method and includes these  headers .You might need to reply to
that CORS preflight with the appropriate CORS headers.
References:
Fetch Standard (whatwg.org)
CORS#preflighted_requests
CORS

Related

Getting Around "blocked by CORS policy" Error in Angular App Running Local Instance of API

I am testing our Angular app (running at http://localhost:4200) against a local instance of our Node/Express/MongoDB-based API (which I'm running at http://localhost:3000).
One of the endpoints I'm testing is used to allow our in-house users to download a file. Now, on our actual API URL, we have our CORS policy set (see below for details) - and this is an internal office app run behind a VPN.
But when I try and test this download functionality on my local app running against a local instance of the API, I get this error message:
Access to XMLHttpRequest at
'http://localhost:3000/v0/filegenerator/download?emailDocId=47dh385686e780c18e905&apikey=9d98e41d-44e9-4bbb-ab3d-35b7df5272dc&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJDUkVXTWVtYmVyIjoiNWmNoIjoiU2MDc0ODd9.bA5B5bx4wPSSiVCS_LxTK1gifjtif8dj29sfUBHqpOg'
from origin 'http://localhost:4200' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It
does not have HTTP ok status.
A couple of questions here:
1.) Is this a generic Chrome security error message?
2.) Is there a way I can turn this off, so I can test downloading the file? Or can I only test this by hitting our actual live API?
How can I best get around this in my testing environment?
Added note: I do have a CORS extension - "Allow-Control-Allow-Origin: *
1.0.3" - installed in Chrome, and it's currently set to "Enable Cross-Origin Resource Sharing".
Also, on our backend Node/Express environment, this is our current setting:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
return next();
});
CORS headers are basically a way for a server to say, "I recognize these other servers as sources to send me requests, and it should be safe for the browser." If there is no header present, then only requests that originate from the same server are considered safe.
You should be able to configure your local application to add a the header to the response.
The plain text header would look like
Access-Control-Allow-Origin: localhost:4200
For testing purposes you can use chrome's disable-web-security flag.
Close all your chrome windows.
Run chrome.exe --disable-web-security
That is a general security feature in browsers. You cannot turn it off. One way to get around this is to allow your origin on the server side, by setting the Access-Control-Allow-Origin header. However, this won't work for preflight (OPTIONS) requests, if you don't handle them separately.
If that is not possible (due to 3rd party libs, services, authentication, etc...) you could set up a reverse proxy in Angular, which allows you to tunnel all of your requests. To the browser it looks like your requests are sent to the same domain (and port) as your angular application (and therefore assume to have the same origin).
Just create a proxy.conf.js in your project like so:
const path = "/proxy_path/*";
const proxy = "/proxy_path/";
const pathRewrite = {};
pathRewrite["^" + proxy.slice(0, -1)] = "";
const configs = {
target: 'your_service_url',
secure: false,
changeOrigin: true,
pathRewrite,
logLevel: "debug"
}
const PROXY_CONFIG = {};
PROXY_CONFIG[path] = configs;
module.exports = PROXY_CONFIG;
And use ng serve --host 0.0.0.0 --disable-host-check --proxy-config <PATH_TO_PROXY_CONF> to start it.
I hope this helps!

Juptyer Kernel Gateway CROS

I have a Jupyter KernelGatewayApp running on a VM instance in Google cloud. I defined an API which responds to a GET statement.
If I combine the ip address of the VM instance with the port of the Kernel Gateway and the GET statement with the right parameters, I get the desired result.
However, I would like to call the API using a javascript button on another site. This doesn't work as the browser is first sending an OPTIONS statement which I don't manage to respond to correctly.
Concretely, I have the following:
Running Jupyter Kernel Gateway on port 8888 : 33.44.567.789:8888
Working API : 33.44.567.789:8888/api?fname=john&lname=doe
Other website where a javascript button calls the above API : johndoe.me
Returns following error on requestor (browser) side:
XMLHttpRequest cannot load
http://33.44.567.789:8888/api?fname=john&lname=doe. Request header
field Content-type is not allowed by Access-Control-Allow-Headers in
preflight response.
Generates following message on server:
INFO:tornado.access:200 OPTIONS /api?fname=john&lname=doe
(xx.xxx.xx.xxx) 1.2 ms
Because of the thing I read here I added all different sort of parameters when launching the Jupyter Kernel Gateway:
jupyter kernelgateway --KernelGatewayApp.api='kernel_gateway.notebook_http' --KernelGatewayApp.seed_uri='/home/dummy_gmail_com/code/test_api.ipynb' --KernelGatewayApp.allow_origin='http://johndoe.me' --KernelGatewayApp.allow_methods='GET,OPTIONS,POST' --KernelGatewayApp.allow_credentials='true' --KernelGateway.allow_headers='Origin, X-Requested-With, Content-Type, Accept, content-type' --KernelGatewayApp.expose_headers='Origin, X-Requested-With, Content-Type,Accept' --KernelGatewayApp.answer_yes=True
The issue seems to be that the browser is issuing an OPTIONS instead of a GET but I'm not really sure. Is this linked to the cross origin fact ? Is there a way to handle this correctly or a way around this ?
Having had the same problem I found that CORS requests served by Jupyter Kernel Gateway worked with the following parameters:
jupyter kernelgateway --KernelGatewayApp.api='kernel_gateway.notebook_http' --KernelGatewayApp.seed_uri='/home/dummy_gmail_com/code/test_api.ipynb' --KernelGatewayApp.allow_origin='http://johndoe.me'
(Using OP's domains etc. for consistency.)
The parameter KernelGatewayApp.allow_origin='*' also worked/Solved the problem.
However I did go wrong prompted by the initial browser console error message which ran:
Access to fetch at 'http://localhost:8889/convert?degrees=164' from origin
'http://localhost:3000' has been blocked by CORS policy:
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.
This prompted me to set the request mode to 'no-cors'. The effect of this is to prevent an Origin header being sent with the request. Under these circumstances no amount of tinkering with the kernel gateway parameters resulted in a successful response.
Also when specifying the Allow Origin header as anything other than '*' it needs to be an exact string match to the 'Origin' header. For example:
Allow-Origin: http://127.0.0.1 does not match Origin: http://localhost
Allow-Origin: localhost does not match Origin: http://localhost
Allow-Origin: http://localhost/ does not match Origin: http://localhost
Allow-Origin: http://localhost does not match Origin: http://localhost:3000
etc.
as you can see with service /siteupdate, you can allow origin on a per service basis

Node-Express-CORS issue

Ionic 2
I am using login provider but when i set the access control to
res.header('Access-Control-Allow-Origin', '*');
It is not working
But it works properly when i use
res.header('Access-Control-Allow-Origin', 'http://localhost:8100');
It is working
but now i want to deploy my app up on phone device i need to set it to wild card res.header('Access-Control-Allow-Origin', '*');. since my app on phone not working on http://localhost:8100 anymore
Anyone can help me solve this problem ?
If you are making a preflighted request then the wildcard is forbidden in the Access-Control-Allow-Origin header.
You can read the Origin request header in order to find out the origin. Then you can test it against a list of allowed origins (you could also assume that any origin is OK, but for a preflighted request there is a good chance that complete public access would be a security risk). Finally you can copy it into the Access-Control-Allow-Origin response header.
How is your HTTP request from your app looks like?
Look for "Types of CORS requests" in this article.
If your HTTP request is a simple one, i.e.
Method is HEAD, GET, or POST
Only have these headers
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type of application/x-www-url-encoded, multipart/form-data, or text/plain
If your HTTP request is a simple one, preflight is not needed. And Access-Control-Allow-Origin with * is accepted by the mobile app.
Otherwise, a preflight request will be made (i.e. OPTION request) and Access-Control-Allow-Origin of * will be ignored. It must be fully specified like http://localhost:8100.

Interacting with expressjs on another server throwing Access-Control-Allow-Headers errors

I am trying to implement Spika web chat ([http://spikaapp.com/][1]) on my Amazon server. I have my website code on one server instance and Spika chat server on another server instance. Spika chat server is up and running. Now when I try to interact with the server on my website I get this error :
XMLHttpRequest cannot load http://example.com:8000/spika/v1/user/list/Boom?_=1468157726669.
Request header field access-token is not allowed by Access-Control-Allow-Headers
in preflight response.
Earlier I had the CORS error I resolved it referring this : http://enable-cors.org/server_expressjs.html
Now I can login but my client but soon after login I get the above error. My current expressjs API handler code for enabling CORS :
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
next();
});
Thanks in advance for the help.
The server (that the POST request is sent to) needs to include the Access-Control-Allow-Headers header (etc) in its response. Putting them in your request from the client has no effect.
This is because it is up to the server to specify that it accepts cross-origin requests (and that it permits the Content-Type request header, and so on) – the client cannot decide for itself that a given server should allow CORS.
When you start playing around with custom request headers you will get a CORS preflight. This is a request that uses the HTTP OPTIONS verb and includes several headers, one of which being Access-Control-Request-Headers listing the headers the client wants to include in the request.
You need to reply to that CORS preflight with the appropriate CORS headers to make this work. One of which is indeed Access-Control-Allow-Headers. That header needs to contain the same values the Access-Control-Request-Headers header contained (or more).
https://fetch.spec.whatwg.org/#http-cors-protocol explains this setup in more detail.
I solved it using https://www.npmjs.com/package/cors. Thanks for all your help guys :)

Node Express Mongoose MongoDB CORS failure

I am using Node/Express/Mongoose/MongoDB on a Debian VPS webserver but for some reason the online CORS request is not firing. Let me just say that everything works perfectly on my local server.
When I upload it to my Debian VPS webserver however the cors request never goes through. I know this because the debug logs never fire. The MongoDB server is running AND the node/express server is running. I have npm reinstalled express/mongoose and even the cors addon MANY times and do not think it's an issue with those...
I have tested things on the server with cURL -H w/ the -origin flags. THE RESPONSES RETURN CORRECTLY in the console. This leads me to believe that the CORS requests are being blocked somehow (maybe by the browsers??) and the express servers are never even reached. I have tried starting browsers with no security flags to no avail also... ONE strange fact is that when the responses do return w/ cURL, they sometimes list different origins even though I specify one origin with the flag. Confusing...
I have tried changing access-origins MANY different times and ways. I have tried allowing all of them. I have tried allowing the ones specific to the requests... I have tried using the apache2 header mod and using an .htaccess file to allow cors. I have also tried the PHP header for it to no avail.
url: www.kensnote.com
Browser error responses are as follows:
Chromium-browser: "Failed to load resource"
Firefox: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:10005/threadpreview. (Reason: CORS request failed).
Firefox Firebug Request Headers:
Accept application/json, text/javascript, /; q=0.01
Accept-Encoding gzip, deflate Accept-Language en-US,en;q=0.5
Cache-Control max-age=0 Connection keep-alive DNT 1 Host
localhost:10005 If-None-Match W/"ssUy2L+Up13MCm2LISgPtQ==" Origin
http://www.kensnote.com Referer http://www.kensnote.com/
User-Agent Mozilla/5.0 (X11; Linux i686; rv:39.0) Gecko/20100101
Firefox/39.0
In a browser implementing CORS, each cross-origin GET or POST request
is preceded by an OPTIONS request that checks whether the GET or POST
is OK.
Basically, for CORS, Firefox will send a preflight options check before the real request.
In your server code, you should send an OK response to the OPTIONS request. Check the following example code that can be used in a route (or middleware):
res.header("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "PATCH, POST, GET, PUT, DELETE, OPTIONS");
if ('OPTIONS' === req.method) {
return res.send(200);
}

Resources