OPTIONS request asks for authorisation header - java

Here is my web.xml file:
https://pastebin.com/SSMu7qKb
And I try to send a GET request from my application with the following headers
'Content-Type': 'application/json',
'Authorization': "Basic ZGVtbzpkZW1v",
'Cache-Control': "no-cache"
to http://localhost:8080/engine-rest/user
I traced my request using Postman. Here are the headers in the request:
[{“key”:“Access-Control-Request-Method”,“value”:“GET”,“description”:""},
{“key”:“Origin”,“value”:“http://evil.com/",“description”:"”},
{“key”:“X-DevTools-Emulate-Network-Conditions-Client
Id”,“value”:“6B279966ED84E2BE5D06B4F083711A81”,“description”:""},
,{“key”:“Access-Control-Request-Headers”,“value”:“authorization,cache-control,content-type”,“description”:""},{“key”:“Accept”,“value”:"/",“description”:""},
{“key”:“Accept-Encoding”,“value”:“gzip, deflate, br”,“description”:""}
,{“key”:“Accept-Language”,“value”:“en-US,en;q=0.9”,“description”:""},
{“key”:“Authorization”,“value”:“Basic ZGVtbzpkZW1v”,“description”:""}]
If I add an Authorisation header in Postman to the ones I have above, I can send the request. Otherwise I get the error code 401 (Unauthorized). But OPTIONS shouldn’t ask for authorisation.
Here is the code for the filter:
https://github.com/quickhack/tomcat/blob/master/src/main/java/org/apache/catalina/filters/CorsFilter.java
The CorsFilter is the first filter in my web.xml file and in CorsFilter.java if the request is identified as Preflight it will not pass go to the next filter(see handlePreflightCORS method). So normally when I have an Preflight request it should not check for authorisation. So why do I get an error 401 ?

Related

Can not send POST with body

I have issue in my application. I have various REST enpoints which are working fine. But now I want to send POST request with body. I already have 2 endpoints for POST method, but data are send using PathParam.
I created new endpoint, but when I send request I am getting CORS error. When I use the same endpoint without body in request everything is okay but of course at backend side I do not get any data from frontend (I have breakpoint inside method).
this is how I send request from my angular application:
post(requestUrl: string, body?: any): Observable<any> {
return this.httpClient.post<any>(this.API_URL + requestUrl, {password: 'test'});
}
After sending request I got:
Access to XMLHttpRequest at 'http://localhost:8080/...' from origin 'http://localhost:4200' 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 I send request like this (without body) this endpoint works fine:
post(requestUrl: string, body?: any): Observable<any> {
return this.httpClient.post<any>(this.API_URL + requestUrl);
}
At backend side I have added settings for CORS:
return Response.ok(object).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.allow("OPTIONS").build();
When I am sending request from Insomnia everything is ok - I can send body and I am getting sent data on backend.
Should I somehow set request headers at frontend side?
Here is my AdminApiController class:
#Path("/admin")
#RequestScoped
public class AdminApiController extends BaseApiController {
#Inject
private AdminAssembler adminAssembler;
#POST
#Path("/login")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response login(LoginRequest request) {
return Response.ok(adminAssembler.login(request))
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.header("Access-Control-Allow-Headers", "Content-Type")
.allow("OPTIONS").build();
}
}
When your angular application sends a JSON payload in a POST request, it probably adds the header Content-Type: application/json. This header classifies the POST request as a "non-simple" request (that is, a request that cannot result out of an HTML <form> element without additional Javascript). Such "non-simple" requests cause to browser to make a preceding preflight request, that is an OPTIONS request with headers
Origin: http://localhost:4200
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
to which the server must respond with an Access-Control-Allow-Origin header and Access-Control-Allow-Headers: Content-Type. If it does not, the browser will not make the POST request and show an error like you observed.
Your Java code covers only #POST, not #OPTIONS, that's why the server does not respond to the preflight request with the necessary headers. How best to handle the OPTIONS requests for all endpoints on your server is a question for Java experts (which I am not).
You need to define your httpOptions.
Try this.
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
post(requestUrl: string, body?: any): Observable<any> {
this.httpClient.post<any>(this.API_URL + requestUrl, {password: 'test'}, this.httpOptions)
}
Let me know if it worked for you.

Fetch request failing due to CORS missing token in Firefox

When trying to issue a POST request in firefox the following error messages come up:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.net/graphql. (Reason: missing token 'content-type' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.net/graphql. (Reason: CORS request did not succeed).
The same request succeeds in Chrome. The request I am sending is:
method: 'POST',
headers:{
'x-client-id': '123',
'content-type': 'application/json; charset=UTF-8'
},
body: JSON.stringify({
query: "query ..."
})
})
.then(res => res.json())
.then(console.log);```
I am issuing this request while on another https origin.
My setup in my code for cors is simply the spring annotation:
```#CrossOrigin(allowedHeaders = {"content-type", "x-client-id"})```
You will need these headers:
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header Content-Type: text/html;
charset=utf-8
at the target in order to allow CORS. If you have no access to the remote stuff, then use your server as a proxy and send the request from there, return the response to your browser.

error : use 'application/json' Content-Type and raw POST with json data

The error message
error : use 'application/json' Content-Type and raw POST with json
data
is being appeared from cyclos application inside plivo console which a third API that need to be integrated in cyclos through
Gateway URL: https://api.plivo.com/v1/Account/auth-id/Message/
HTTP username:xxx
HTTP password: ****
HTTP headers
{
'content-type': 'application/json',
}
HTTP request type: POST
HTTP request POST body
{
"src":"+xxxx",
"dst":"+xxx",
"text":"some test"
}
Can you try sending header as 'Content-Type' instead of 'content-type'.
There are some implementations where field-names are case-sensitive (Like an age-old bug in PHP!).

How to enable cors issue in Angular2 with Backend as Liferay server

I am new to Angular2. I have to create new Angular application and Need to use services from Liferay server.
But When I call the Service using below code, it is giving Cors error.
var headers = new Headers();
headers.append('Access-Control-Allow-Origin', '*');
headers.append("Content-Type", "application/x-www-form-urlencoded");
let params: URLSearchParams = new URLSearchParams();
this.http.get(localStorage.getItem('domainName')+'/service-name', {headers: headers})
.subscribe(response => {
// login successful if there's a jwt token in the response
console.log('Response'+response.json());
});
My backend method is GET and I have added Cors filter property in my /webapps/Root/web.xml file
BUt in browser console it is giving below error:
XMLHttpRequest cannot load http://localhost:9080/service-name. 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:4200' is therefore not allowed access. The response had HTTP status code 401.
This error comes up when the backend's response does not have the necessary Access-Control-Allow-Origin header. Please double check that the backend's headers are properly configured. Also, the frontend's request does not have to have the Access-Control-Allow-Origin header ever.

Rest Assured post request with cookie and content type Text/plain

I'm using rest assured to test API's.am facing issues in making a request with below configuartion using rest assured.
Request type : POST
Headers:
Content-Type :text/plain
api-key : 12263783493
user : emailid
Cookie : changesetId=4604
Body type-: raw : Text
applyToAllMapsOnController=false&applyToAllMaps=false (this is the text in the request body to be passed)
Below is what i tried but I'm getting 400 bad request
Response response= (Response) RestAssured.given().
header("Content-Type", "text/plain").
header("charset","utf-8").
header("api-key","dV43+Rbr9uncPd&;ydiQx]uUFX2").
header("user","P2899445,Bhavan Ramakrishnappa").
cookie("cookie", "changesetId="+Number).
body("applyToAllMapsOnController=false&applyToAllMaps=false").
when().
post(servicelevel);
can someone help me how to pass cookie in header and raw text in the body.
You can do multiple things to Debug the issue.
Try passing ("cookie", "changesetId="+Number) as a header
use when().log().all so that you can see what is the Request being Sent.

Categories