Google Cloud Storage ignoring access control origin headers - ajax

I'm trying to get files via AJAX from google cloud storage on my local host. I have done the following:
Set the CORS for my bucket via gsutil:
gsutil cors set cors.json gs://my-project
where the cors.json file is:
[
{
"origin": [
"*"
],
"responseHeader": ["Origin", "Accept", "X-Requested-With", "Authorization", "Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token"],
"method": [
"GET",
"OPTIONS"
],
"maxAgeSeconds": 1
}
]
I have verified it with gsutil cors get gs://my-project
Then for each file I have made it public, both through the node.js client library when the file is uploaded:
bucket.file(object.name).makePublic()
through the console, and through the gsutil:
gsutil -m acl set -R -a public-read gs://my-project
Then in my ajax request, I also send headers:
$.ajax({
method: "GET",
url: "https://googleapis.com/storage/v1/b/my-project/o?delimiter=audio",
headers: {
'Access-Control-Allow-Origin': '*'
},
crossDomain: true,
}).done((data) => {
console.log(data)
})
and I still get a cors error:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access.
How do I get past CORS?

You're using "googleapis.com" instead of "www.googleapis.com". Add the "www" and your code will work.
It looks like you're not doing any authentication, so you'll also need to make sure that your bucket allows anonymous users to list objects (gsutil acl ch -g allUsers:R gs://bucket-name will set that).
Next, for anonymous requests, it's a good practice to add an API key parameter associating the request with your Google Cloud project. GCS will allow completely anonymous requests, but they may be blocked if they get too frequent.
Finally, the CORS policy on a bucket is only respected by the XML API. The JSON API, which is the one with the endpoint of "www.googleapis.com", will happily respond to cross-origin requests without the need to set any special properties on the bucket.

Related

CORS policy error with AWS API Gateway in React

I am trying to set up an API Gateway to call another lambda function that will upload an image to S3. The feature works well when I am using an app like POSTMAN, however when I run the browser using React I am getting the following error.
Access to fetch at 'https://.../upload' from origin 'http://localhost:3000' 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.
In my API Gateway I have the following configuration for that method
Gateway Responses for UserUpload API: default 4XX (not checked), default 5XX (not checked)
Methods: post (checked), options (checked)
Access-Control-Allow-Methods: options, post
Access-Control-Allow-Headers: '*'
Access-Control-Allow-Origin: '*'
This API uses an authorizer, I am using the one provided by Auth0 and have not edited the code at all.
And the function that my authorizer calls returns the response like the below (eg happy path):
exports.handler = async (event) => {
//do data checks and upload to s3
return {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Origin": "*",
},
statusCode: 200,
body: JSON.stringify({ message: "success" }),
};
This is my first time setting up both a lambda function, authorisation provider and API Gateway so I might be missing something obvious. I have also tried added mode: no-cors to my fetch POST requests however they still fail in a very similar way.
From what I can tell by looking at the logs of the authorizer and the lambda function that uploads the images, is that they are not even being called. So it appears the CORS error is with the API Gateway.
I have seen in a few tutorials that in their aws template yaml files they add an option AddDefaultAuthorizerToCorsPreflight as False. I can't see this anywhere in the API Gateway console.
Update: I have tested my function with the custom authoriser turned off and it works. So I know that CORS works for the options method, and for the returned request on the lambda function. It is the custom authoriser that is the problem.
The flow is currently:
Method Request - Auth: my-auth-0-authorizer
Integration Request - Type: Lambda_proxy
Lambda function
Integration response - [greyed out Proxy integrations cannot be configured to transform responses]
Method Response: HTTP Status: Proxy (with Access-Control-Allow-Origin in the response headers)
What do I have to do differently or change to allow my authoriser to respect the CORS config?
Update: After leaving my API Gateway for a day, successful responses are now working (using the flow mentioned above). I am not sure if there was a glitch in the system or there was unexpected occurring but it is now working. I am still getting a CORS issue but now only with bad responses.
The custom authoriser fails by return context.fail("Unauthorized"); and when this occurs my browser gets a CORS error. Do I have to set up special gateway responses for 4XX responses?

Access to fetch has been blocked by CORS policy. It does not have HTTP ok status

So I'm building a react app that fetches JSON data from a spring boot rest api built by me.
Here is the code for the fetch method:
componentDidMount() {
fetch(`http://localhost:8080/students`, {
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then((response) => response.json())
.then((data) => this.setState({students: data}));
console.log(this.state.students);
}
However when I run the program it gives me an error saying:
Access to fetch at 'http://localhost:8080/students' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Can anyone help me?
I'm not 100% familiar with Spring Boot, but the general solution to this problem is to make sure your service responds with an Access-Control-Allow-Origin header that matches the origin (localhost in your example) if it is not the same origin as your service.
Adding "Access-Control-Allow-Origin": "*" would do it for your development purposes. In production, you probably want to be more specific with which origins are actually allowed.
Have a look at this resource for more information about CORS: https://enable-cors.org/
It is the same origin policy implemented in your browser that is causing this. It specifies that a browser should allow scripts in one web page to access resources on another, but only if they are from the same origin. If they are not, you can specify that they are allowed by specifying the header I mentioned above. You may also need to specify allowed verbs and headers as well, depending on what you're doing.

Using Proxy , Cookies not sent in angular 4 app using withCredentials set to true

I am host angular 4 app on my localhost , Since I need to make api request to my backend which is hosted on web (say https://example.com ) I am using proxy . Here is my proxy config file.
"*": {"target":"https://example.com",
"secure": false,
"logLevel": "debug",
"changeOrigin": true }
So that every request I make goes through the target url . When I make my first request to login page with credentials included I receive cookies in response.But then when I make another request ( POST ) to https://example.com/images I am redirected to the login page . I can see in my network that there are no cookies being sent with the Request headers, however I did receive them from my first login request . I checked out many solutions to this problem. Many of them asked to include {withCredentials=true} in my ajax request which I did in every request.Here is my request
$.ajax({
url: "https://example.com/images",
type: "POST",
crossDomain:true,
headers: {
// includes necessary headers .
},
xhrFields: {
withCredentials: true
},
data:data1 ,
//data1 is json formatted
success: function (res) {
console.log(res)
},
error: function (xhr, status) {
console.log(status);
}
});
But this did not solve the problem. I suspect the cookies are getting lost due to proxy , or the browser is not handling them correctly. I checked I have allowed third party cookies . I need to send those session cookies with this second request . I tried to manually add them but I did not find a way to get and send them along with this request. how can I tackle this issue ? If I remove proxy then I will get the CORS issue . I do not have access to the backend server. hence I tried handling CORS using proxy which works correctly for login request. But this second request is not being sent with cookies. Anyone who can help with this ?
Why are you using jQuery in your angular app, and why use it to do ajax requests, if angular provides an http client?
You better use it and then, use interceptors to add headers to the requests.
When using Angular, do it the Angular way. And use its tools/libraries/patterns.

Cross-Domain Ajax Requests WSO2 IS

curl -v -X POST -H "Authorization: Basic <base64 encoded client id:client secret value>" -k -d "grant_type=password&username=<username>&password=<password>" -H "Content-Type:application/x-www-form-urlencoded" https://localhost:9443/oauth2/token
(from https://docs.wso2.com/display/IS520/Resource+Owner+Password+Credentials+Grant
)
This 'curl' command works perfectly. But when try to call it through ajax:
$.ajax({
type: 'POST',
data: 'grant_type=password&username=admin&password=admin',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic Z0hLUlA3eThYTmJydl9JR1pJemxDQ1VJQlo0YTozT2VLaUlmUVViMk1yZzZ2YU5uQVFsWFpDU29h'
},
url: 'https://localhost:9443/oauth2/token',
success: function(data) {
console.log(data);
}
})
};
I got this error: "XMLHttpRequest cannot load https://localhost:9443/oauth2/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access."
How can I configure WSO2 IS to deal with it? Or is there an alternetive for this?
There is a similar issue with WSO2 API Manager (WSO2 API Manager CORS). But there is no such directory '/repository/deployment/server/synapse-configs/' in WSO2 IS.
This is the expected behaviour when cross origin resource sharing (CORS) is not enabled on Identity Server. In fact you can enable CORS for Identity Server. Check [1] on how to do it.
[1] http://hasanthipurnima.blogspot.com/2016/05/applying-cors-filter-to-wso2-identity.html
I don't think the Token API of IS returns CORS headers. To get this working, you can front Token API of IS by API Manager. By default, APIM returns CORS headers in all REST APIs you create in it.
In fact, API Manager ships an API (i.e. https://localhost:8243/token) which fronts the token API of IS (i.e. https://localhost:9443/oauth2/token) (note: APIM has certain IS features installed in it). But it does not return CORS headers too. To make it return CORS headers, you should follow that SO link you have mentioned.
Another simple option is, if you only need CORS headers, you can simply front Token API of IS by another custom services which returns CORS headers in the response.

ajax get request to Office365 REST Api fails CORS?

I'm attempting to make an ajax GET request to the Office365 RESTful API service from my local server, but am running into cross-domain HTTPRequest errors. The following is a sample of my 'get-files-at-root' attempt:
$.ajax({
url: 'https://[sharepoint_site]/_api/v1.0/me/files?access_token='+token,
type: 'get',
dataType: 'json',
success: function(data) {
if (success){
success(data);
}
},
error: error
})
I'm getting the following response from the server:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403.
I've tried sending the access token as a header parameter:
headers: {'Authorization': 'Bearer '+ token}
but this had the same result.
Any ideas on what I'm doing wrong?
(Background: I'm trying to create my own Office365 'file picker' on the client because I couldn't find an available library for OneDrive Business that supplies this.)
Office 365 Files API and SharePoint REST have just introduced support for CORS.
https://msdn.microsoft.com/en-us/office/office365/howto/create-web-apps-using-CORS-to-access-files-in-Office-365
What you were trying to do is exactly how it works. The service will respond to the OPTIONS pre-flight request with an Access-Control-Allow-Origin header.
The authorization in the request must be an Azure Active Directory issued OAuth2 implicit grant access token.
You have no idea about CORS. Read the specification: http://www.w3.org/TR/cors/
In your case you have to allow null origin, since we are talking about localhost. You have to allow the methods and the headers you send, even the content-type header. You have to allow sending credentials, which you can get in the Authorization header. You have to handle OPTIONS requests with 200 ok.
response.setHeader("Access-Control-Allow-Origin", "*");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Allow-Methods", "POST, GET");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
Can you try with setting the Access-Control-Allow-Origin in header as shown below.
headers: { 'Access-Control-Allow-Origin': '*' }

Resources