Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CORS with Ajax is not working well. #3312

Closed
iabughosh opened this issue Jul 23, 2019 · 29 comments
Closed

CORS with Ajax is not working well. #3312

iabughosh opened this issue Jul 23, 2019 · 29 comments
Labels
area/security kind/bug Something isn't working
Milestone

Comments

@iabughosh
Copy link

Calling REST resources using Ajax is not working fine
I am trying to call a service sides on my localhost:8080/person (POST) through VueJS app on my localhost:8084 but it is not working. I tried to enable CORS config. in application.properties with the below :

quarkus.http.cors=true
quarkus.http.cors.origins=http://localhost:8084
quarkus.http.cors.headers=accept, authorization, content-type, x-requested-with
quarkus.http.cors.methods=GET, PUT, POST

Expected behavior
It should work fine and be able to call my resource.

Actual behavior
Browser logs error :

Access to XMLHttpRequest at 'http://localhost:8080/person' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Even it is not reaching to my ContainerRequestFilter code.

To Reproduce
Steps to reproduce the behavior:

  1. Any REST resource. in my case I used POST method with application/json.
  2. Try to call it from different app (port) using Ajax library (jQuery or Axiom).

Configuration

> quarkus.http.cors=true
> quarkus.http.cors.origins=http://localhost:8084
> quarkus.http.cors.headers=accept, authorization, content-type, x-requested-with
> quarkus.http.cors.methods=GET, PUT, POST

Environment (please complete the following information):

  • Output of uname -a or ver: Darwin SDG0268LMAC 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64
  • Output of java -version: OpenJDK Runtime Environment Corretto-8.202.08.2 (build 1.8.0_202-b08)
  • GraalVM version (if different from Java): graalvm-ce-19.0.2
  • Quarkus version or git rev: 0.18.0

Additional context
Event if CORS is disabled same issue is produced.

@iabughosh iabughosh added the kind/bug Something isn't working label Jul 23, 2019
@owennewo
Copy link

owennewo commented Aug 2, 2019

Do you have to go the cors route? I'd just configure npm (vuejs) to proxy anything on localhost:8084/person to localhost:8080/person. In production on kubernetes this sort of thing is better done with an 2 ingresses sharing same dns.

Edit: if you staying with cors, try using your real ip, I've had trouble with localhost in the past

@Ladicek
Copy link
Contributor

Ladicek commented Aug 2, 2019

I took a look and it seems this is caused by the way how the CORS servlet filter and the RESTEasy servlet filter interact. I'll continue digging on Monday.

@iabughosh
Copy link
Author

That makes sense now. Because request is not being reached to quarkus request filter so it must be stopped by some earlier stage. Thanks for the update.

@kaganem
Copy link

kaganem commented Aug 7, 2019

Found two more strange scenarious:

  1. If I put * in quarkus.http.cors.origins - Quarkus block everything. Expected to allow all. Adding custom ContainerResponseFilter may fix it.
@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        MultivaluedMap<String, Object> headers = responseContext.getHeaders();
        headers.putSingle("Access-Control-Allow-Origin", "*");
        ...    
        headers.putSingle("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
    }

}
  1. PATCH HTTP method is not respected. Was not able to get it working even with explicit declaration in ContainerResponseFilter
headers.putSingle("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE, PATCH, HEAD");

For some reason PATCH requests are not catched by ContainerResponseFilter at all.

@Ladicek
Copy link
Contributor

Ladicek commented Aug 7, 2019

Ad 1., that's because the CORS servlet filter expects to find the value of the Origin header in the set of configured allowed origins. Supporting * is probably a good idea.

Ad 2., that's probably also because the CORSFilter and ResteasyFilter interact in a weird way. I didn't have time to look into it yet, but I should get to it this week.

@Ladicek
Copy link
Contributor

Ladicek commented Aug 9, 2019

Ad 1. again: the CORS filter already allows all origins, if quarkus.http.cors.origins is not set. Not sure if adding support for * is worth it.

@dhartford
Copy link

Is this still a WIP? Just doing a check-in to see if there is something in motion (npm dev UI environment with quarkus dev backend environment). The scenario I have is a quarkus w/ undertow, resteasy, and smallrye-openapi and using Postman not getting any of the CORS-associated headers in the response for the rest/openapi endpoint (no Access-Control-Allow-Origin header entry).

Tested quarkus 0.20.0 and 0.23.1

application.properties

quarkus.smallrye-openapi.path=/openapi
quarkus.http.cors=true
#testing with and without, no difference
#quarkus.http.cors.origins=http://localhost:3000,http://localhost:8080
#testing with and without, no difference
#quarkus.http.cors.exposed-headers=Access-Control-Allow-Origin

@Heni-ghodbane
Copy link

I have tried the last version 0.23.1 but it doesn't work: Back-end still rejects requests from a different domain, respectively my react Front-end app still receive
Access to XMLHttpRequest at 'http://localhost:8080/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Is this issue still not fixed? Is there is any suitable alternative?

@Ladicek
Copy link
Contributor

Ladicek commented Oct 8, 2019

I'm testing CORS using http://www.test-cors.org on Quarkus 0.23.2 and also the latest master branch, with this config file:

quarkus.http.cors=true
quarkus.http.cors.origins=http://www.test-cors.org
quarkus.http.cors.headers=accept,authorization,content-type,x-requested-with,x-foobar
quarkus.http.cors.methods=GET,POST,PUT

It seems to work just fine.

@dhartford
Copy link

Just tested 0.23.2, hopefully I'm the minor but still not getting the Access-Control-Allow-Origin headers (tested both mvn quarkus:dev and a production build running the java -jar *-runner.jar).

application.properties

quarkus.smallrye-openapi.path=/openapi
quarkus.http.cors=true
#testing with and without, no difference
#quarkus.http.cors.origins=http://localhost:3000,http://localhost:8080
#tried this related to potential issue with localhost, no difference
#quarkus.http.cors.origins=http://127.0.0.1:3000
#testing with and without, no difference
#quarkus.http.cors.exposed-headers=Access-Control-Allow-Origin
#testing with and without, no difference
#quarkus.http.cors.headers=accept, origin, authorization, content-type, x-requested-with
#testing with and without, no difference
#quarkus.http.cors.methods=GET,PUT,POST,OPTIONS

@Ladicek
Copy link
Contributor

Ladicek commented Oct 9, 2019

@dhartford Can you please provide more details? For example, do you have a reproducer using curl (or HTTPie)?

Also, do you perhaps use some kind of a caching proxy or something similar? I've noticed that the Quarkus CORS handler should at the very least include Vary: Origin (and perhaps other values for the Vary header), but that didn't prevent it from working in the basic local usecase.

@dhartford
Copy link

Using postman and curl for direct functional testing, and 'npm start' with a webapp with a fetch for applied testing (which states the no Access-Control-Allowed-Origin header problem), all localhost or 127.0.0.1 without any caching proxy.

curl -v http://localhost:8080/openapi/app

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /openapi/app HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< **Content-Type: application/json**
< **Content-Length: 40**
< 
* Connection #0 to host localhost left intact
{ "APP_NAME": "Changed App Name Here so length may be different"}

@Ladicek
Copy link
Contributor

Ladicek commented Oct 9, 2019

Ah, so it's on the OpenAPI endpoint, I didn't try that. I'll check tomorrow, thanks for the info.

@iabughosh
Copy link
Author

iabughosh commented Oct 10, 2019

Dears,
I've generated the issue again with latest version. I've created two repositories for this. One for Quarkus as the backend APIs and the other one is the VueJS as front end.

Quarkus : https://github.com/iabughosh/microprofile-health
VueJS : https://github.com/iabughosh/VueJs

I will do some debugging from my end too.

Regards.

@Heni-ghodbane
Copy link

The same issue is still produced as @dhartford describe, even with the latest version 0.23.2
Hopefully, it will be fixed in the next release!

@luszczynski
Copy link
Contributor

I have the same issue as well. When I use

quarkus.http.cors.origins=http://localhost:8081

is working fine. But when using *

quarkus.http.cors.origins="*"`

is not working no matter what I do.

@Ladicek
Copy link
Contributor

Ladicek commented Oct 21, 2019

Instead of *, just leave the quarkus.http.cors.origins property out.

One other thing I'd like to highlight, because I've seen it in the reports here (I already mentioned this in the other CORS issue): if the request doesn't have the Origin header, the response won't have CORS headers either.

This is perfectly fine per my understanding of CORS. (What's worse is that this doesn't necessarily play well with caching proxy servers. My understanding is that we should at least always include Vary: Origin if CORS is enabled. But that shouldn't be a problem in the investigations here.)

@luszczynski
Copy link
Contributor

@Ladicek you are right. It is working now only with:

quarkus.http.cors=true

@iabughosh
Copy link
Author

Dears,
Is still this considered as a bug ? because for me even if I disabled cors config, I am still facing the same issue !

@ricardozanini
Copy link

Does anyone here have a reproducer with a ReactJS application accessing a Quarkus REST API to demonstrate this error to maintainers?

@Heni-ghodbane
Copy link

Heni-ghodbane commented Oct 24, 2019

@iabughosh I think, this issue should be marked as solved.
for me now it's working correctly.
with the configuration as @Ladicek mentioned before.

quarkus.http.cors=true
quarkus.http.cors.origins=http://localhost:3000
quarkus.http.cors.headers=accept,origin,authorization,content-type,x-requested-with,x-foobar
quarkus.http.cors.methods=GET,POST,PUT,OPTIONS

@iabughosh
Copy link
Author

Unfortunately, the main problem - which is disabling the cors still not working fine. I will try these configuration and report back.

@iabughosh
Copy link
Author

Just Tried @Ladicek and it is working fine (which is great :) ); however, it is not working if I disabled CORS. I will close this bug as the main issue is resolved for me.

@luszczynski
Copy link
Contributor

As I said, the only way to make it work on any domain is using only one single CORS property:

quarkus.http.cors=true

If I disable it, the problem still persists. I'm using Quarkus 0.25.0.
IMHO quarkus.http.cors.origins=* should also work, but for now, it isn't.

@Ladicek
Copy link
Contributor

Ladicek commented Oct 24, 2019

Currently, you can achieve "all origins" by simply omitting quarkus.http.cors.origins altogether. I wonder what should be the difference between "no quarkus.http.cors.origins at all" and "quarkus.http.cors.origins=*".

@dhartford
Copy link

@Ladicek For the quarkus.http.cors.origins=* discussion item, I can at least share my experience which may not be related to the catalyst, but may support it. When working in certain regulatory fields, you often have to explicitly list all (security) relevant configuration values, often copying the default value, to show reviewers/auditors the intent as explicitly as possible.
HTH!

@Ladicek
Copy link
Contributor

Ladicek commented Oct 26, 2019

@dhartford In that case, it should be possible to just write quarkus.http.cors.origins=, but I'd expect that in highly regulated fields, allowing all origins wouldn't be what you want :-) Thanks for an interesting case though!

@gsmet gsmet added this to the 0.27.0 milestone Oct 29, 2019
@pallavimanjare
Copy link

I have same issue..i have tried all above ways.but still not work.issue is still there of cors

@OmarBouachir
Copy link

in case you are working with a yaml file this must be your configuration :
quarkus:
http:
cors:
~: true
origins : http://localhost:3000
headers: accept, authorization, content-type, x-requested-with
methods: GET, PUT, POST

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/security kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests