CORS not working with zuul enabled gateway and swagger - java

I am facing strange issue while setting up cors with my swagger gateway and operating on the zuul mechanism gateway has list of microservices. on the click of it will redirect to specific service swagger doc and when I using swagger "Try it out" functionality.
This is how swagger gateway list looks like
problem is that "Try it out" calling option method call to check cross origin operation and failing with 401.
For ex.
This is my swagger gateway url
abc.com/replica-stock/swagger-ui.html
and zuul converts it to following one
replica-stock.com/swagger-ui.html
and for the "Try it out" api check the URL is like this
xyz.com/api/v1/getStock
and I am getting following error in browser console
Access to fetch at 'xyz.com/api/v1/getStock' from origin 'abc.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
and this is my request and response headers look like
Request header
:method: OPTIONS
:path: /replica-stock/api/v1/replicaStocks/13?partCode=1234&usageCode=01
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-IN,en-US;q=0.9,en-GB;q=0.8,en;q=0.7
access-control-request-headers: authorization
access-control-request-method: GET
origin: abc.com
referer: abc.com/replica-stock/swagger-ui.html
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
Response headers
access-control-allow-credentials: true
access-control-allow-headers: authorization
access-control-allow-methods: GET
access-control-allow-origin: abc.com
allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
content-length: 0
content-type: application/json;charset=ISO-8859-1
date: Mon, 17 Aug 2020 06:16:20 GMT
status: 401
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-vcap-request-id: 2b52f4f7-085f-449e-5429-ffbd830cd5db
Can someone help me where I have to fix this cors issue ?

Related

file could not be downloaded in IE 11 when a compressed(gzipped) response is sent to the client

I am trying to download a file from an application through two frameworks. one with struts 1(older framework) and the other with Spring MVC(migrated from old).In Spring migrated application it is showing file could not be downloaded in IE 11 when a compressed(gzipped) response is sent to the client. It is showing "File could not be downloaded". It works fine in chrome as well as in older struts framework. Also if the response is not compressed, file gets downloaded successfully on IE as well on Spring MVC. I cannot really identify the cause here. Requesting some guidance and help to identify this problem.
Request headers is
<code>
Request URL: //edited
Request Method: POST
Status Code: 200 / OK
- Request Headers
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US
Authorization: Basic YW3Rt2aW46dG4V3zdD5EyMz6Q=
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 3521
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=urVBPpjD3QrP6KhkqCK4r8KSAuvKFSVPdp-UXyz-FYSz4W0cQmV9sh!4524586920
Host: localhost:7001
Referer: //edited
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
</code>
Below is the response headers
<code>
Response Headers
Cache-Control: private, no-cache, no-store
Content-Disposition: attachment; filename="Closed DSP01 CRD0037_2019-12-26_133924.csv"
Content-Encoding: gzip
Content-Type: text/csv; charset=UTF-8
Date: Thu, 26 Dec 2019 08:09:23 GMT
Expires: 0
Pragma: no-cache
Transfer-Encoding: chunked
</code>
particular code where compression is done
<code>
if (canUseGzip) {
response.setHeader("Content-Encoding", "gzip");
GZIPOutputStream out = new GZIPOutputStream(response.getOutputStream());
pw = new OutputStreamWriter(out, "UTF-8");
} else {
pw = response.getWriter();
}
</code>
I tried different possibilities and when I tried to explicitly set content-length header ,say,
response.setHeader("Content-Length", String.valueOf(1024));
the file got downloaded successfully in IE. When I googled, I found transfer-encoding and content-length are mutually exclusive and former is already on the response. I don't know why adding content-length worked here and it was required only on the Spring migrated code. File gets downloaded successfully on older struts framework without mentioning the content-length header.
Is there anything specific I am missing here? Is there any other permanent solution as well?
Also how to correctly set the content length? I randomly tried with 1024 and it may fail for some other data.
Any help is appreciated

RESTEasyClient Request - session, cookie

i've sending the "same" request (a simple get-request) to a server and with Postman all works fine and with RestEasyClient it doesn't (401 Unauthorized)...
I looked on both requests by fiddler and saw some differences which might be the cause of the problem (i actually don't know) but at least in my opinion it makes no sense to send these parameters... but i have no idea where to turn it off, it seems to be a default behavior from RESTEasyClient.
Here the postman request:
GET https://xxxx/ping HTTP/1.1
Authorization: Bearer 7e6e4255-0d94-3d29-8527-fb5c8ff8e23b
cache-control: no-cache
Postman-Token: 7d54d38f-ca13-4fb0-8d14-18153f9b2f93
User-Agent: PostmanRuntime/7.3.0
Accept: */*
Host: xxxx
accept-encoding: gzip, deflate
Connection: close
Here the RESTEasyClient-Request:
GET https://tapi002-vpn-api.e-bk.m086/t1/msc-grawe/v1/ping HTTP/1.1
Authorization: Bearer 7e6e4255-0d94-3d29-8527-fb5c8ff8e23b
Host: xxxx
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_144)
Cookie: ROUTEID=.2
My questions are:
Why sends RESTEasyClient Connection: Keep-Alive? Wouldn't it be better to send connection close, because there is no session?!
Why does RESTEasyClient send a Cookie? I don't want and need any cookies...
And by the way: What's the postman token?!
Update:
The Cookie: ROUTEID=.2 causes the error... so the important question is how to remove the Cookie from the RESTEasyClient request header.
Update 2:
The server requested to set the cookie in the token-response... strange... i will try to remove the cookie...
Set-Cookie: ROUTEID=.1; path=/;Secure;HttpOnly; max-age=1200
Why sends RESTEasyClient Connection: Keep-Alive? Wouldn't it be better to send connection close, because there is no session?!
As for Keep-Alive: Because RestEasy uses HTTP/1.1 with connection reuse by default. That doesn't mean a session
Thanks to jokster for this answer.
Why does RESTEasyClient send a Cookie? I don't want and need any cookies...
RESTEasyClient does not send any cookies by default! In this case: Because the server requested the cookie in a request before...
And by the way: What's the postman token?!
Have a look at: What is the postman-token in generated code from Postman?

Content-Type Preflight Handling with AWS API Gateway versus Own Rest Server

What is special with API Gateway, it is not required to include Access-Control-Allow-Headers in the response header.
This is AWS API Gateway Response Header:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 152
Connection: keep-alive
Date: Tue, 11 Oct 2016 02:39:40 GMT
Access-Control-Allow-Origin: *
x-amzn-RequestId: f3838f6a-8f5b-11e6-b13a-XXXXXXX
X-Cache: Miss from cloudfront
Via: 1.1 XXXXXXXXXXX.cloudfront.net (CloudFront)
X-Amz-Cf-Id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==
This is My Own Rest Server Response Header:
HTTP/1.1 200
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Content-Type: application/json
Content-Length: 335
Date: Tue, 11 Oct 2016 02:34:31 GMT
The Problem with My Own Rest Server is that I need include Access-Control-Allow-Headers in the response otherwise I will encounter Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
With AWS API Gateway, I am not encounter that error even the Access-Control-Allow-Headers is not in response header.
According to the documentation here, Content-Type should be allowed by default.
"Apart from the headers set automatically by the user agent (e.g. Connection, User-Agent, etc.), the only headers which are allowed to be manually set are:
Accept
Accept-Language
Content-Language
Content-Type
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded
multipart/form-data
text/plain"
Hope that helps, Ritisha.

Java http request for django rest framework service throws http 406 exception

I hava a django rest framework web service that works fine with httpie and firefox: when I request with httpie I have a json formatted answer and when I request with firefox an html formatted one (httpie is a http client).
Now I'm building java API to communicate with services. I'm using URL class to perform requests.
I can receive html-formatted answers from the server if I don't override the content-type property. So I looked how httpie overrides this property and did the same:
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
connection.setRequestProperty("Accept", "*\\*");
Now the communication end with Http 406 error, which means that client can't accept the answer.
If I use only the content-type property I have no error but still the html-formatted answer
Does anyone know how to solve it?
EDIT (adding requests' header):
httpie:
GET /match/39.3280114/16.241917599999965/0/5/ HTTP/1.1
Host: 127.0.0.1:8001
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: /
User-Agent: HTTPie/0.9.3
java-API
GET /match/39.3280114/16.241917599999965/0/5/ HTTP/1.1
Host: 127.0.0.1:8001
Accept-Encoding: gzip, deflate
Accept: **
User-Agent: Java-API
Solved: I was using the wrong slash for Accept property
Your Accept header is malformed. It should be:
Accept: */*
See RFC 7231 § 5.3.2.
However, */* means “any media type.” If you actually want a specific media type (JSON), you should request it:
Accept: application/json

HTTP gzip encoding with multipart message

I am trying to send a gziped multipart POST to a Tomcat server from a Java application using Jersey. When the multipart request is not compressed, it works perfectly fine. Other types of compressed POSTS work fine, such as sending a single entity XML. I (believe) posting compressed data isn't an HTTP standard, but it does seem Tomcat supports it to some degree.
a working uncompressed multipart post:
POST /myApp/rest/data HTTP/1.1
Content-Type: multipart/mixed; boundary=Boundary_1_23237284_1331130438482
Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXX;Version=1;Path=/myApp/
MIME-Version: 1.0
User-Agent: Java/1.6.0_26
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Transfer-Encoding: chunked
d3
--Boundary_1_23237284_1331130438482
Content-Type: application/octet-stream
Content-Disposition: form-data; filename="uploadFile.war"; modification-date="Wed, 29 Feb 2012 18:01:38 GMT"; size=25343899; name="file"
{binary data here}
--Boundary_1_25179713_1331128929019
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><myXMLEntity>stuff</myXMLEntity>
--Boundary_1_25179713_1331128929019--
When I compress it using the Jersey GZIPContentEncodingFilter() the following headers are sent, and I get back an HTTP 400 with a description of "incorrect syntax"
POST /myApp/rest/data HTTP/1.1
Content-Type: multipart/mixed
Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;Version=1;Path=/myApp/
Accept-Encoding: gzip
Content-Encoding: gzip
User-Agent: Java/1.6.0_26
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Transfer-Encoding: chunked
{binary data here}
Is what I'm trying to do possible? Should the Content-Type actually read multipart/x-gzip? I notice that when it gets compressed, the boundary text gets left off of the Content-Type header - is this also a problem?
I ran into this same issue (or something very similar) and tracked it down to the Content-Type header missing the boundary parameter when using GZIPContentEncodingFilter. I was able to work around it by using MultiPartMediaTypes.createFormData() when setting the type of the entity I was POSTing from the Jersey client. Doing so makes sure the boundary parameter is set earlier than Jersey would automatically set it, which seems to be too late when using the GZIPContentEncodingFilter for compressing the request entity. There is an equivalent method for multipart/mixed.
I don't have an IDE handy but something similar to this:
// client is a Jersey Client object
client.resource(uri).entity(multipartFormData, MultiPartMediaTypes.createFormData()).post(ClientResponse.class);
All that said, this will still only work if your server is able to handle GZIP compressed requests.
IMO you can't do this that way, because the server and the client need to agree on how to communicate (e.g. zip compression). HTTP is designed as request/response and server can return what the client can support.
The client sends request to the saying, "Hey server, I need this resource and I support gzip, so you can return gzip if you can". :)
Imagine a situation that your client sends to the server a few megabytes in gzip, but the server doesn't support this.

Categories

Resources