Spring Oauth2 CORS issue - java

I set CORS to allow few custom headers. Below is the Response Header -
Response Headers { "Date": "Mon, 14 Mar 2016 10:11:59 GMT",
"Server": "Apache-Coyote/1.1", "Transfer-Encoding": "chunked",
"Access-Control-Max-Age": "3600", "Access-Control-Allow-Methods":
"POST, GET, OPTIONS, DELETE, PUT", "Content-Type":
"application/json", "Access-Control-Allow-Origin":
"*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Headers": "X-Requested-With, Authorization,
Content-Type, Authorization_Code, User_Credentials,
Client_Credentials" }
Above response header should mean that API can be consumed from all the origins with following headers: Authorization, Content-Type, Authorization_Code, User_Credentials, Client_Credentials
I can pass all headers and consume APIs from all origins.
PROBLEM -
Requests with Authorization APIs are not being allowed. Authorization is a header with which Oauth token is passed like this - Authorizatio = Bearer ct45tg4g3rf3rfr5freg34gerfgr3gf (Bearer token).
corsclient.js:609 OPTIONS http://54.200.113.97:8080/supafit-api/users
sendRequest # corsclient.js:609(anonymous function) #
corsclient.js:647b.event.dispatch # jquery-1.9.1.min.js:3v.handle #
jquery-1.9.1.min.js:3
/client#?client_method=GET&client_credentials=false&client_headers=Authoriz…nable=true&server_status=200&server_credentials=false&server_tabs=remote:1
XMLHttpRequest cannot load
http://54.200.113.97:8080/supafit-api/users. Response to preflight
request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://client.cors-api.appspot.com' is therefore not
allowed access. The response had HTTP status code 401.
EDIT:
Here is the Rest Client test of that API -
Response Header -
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Max-Age: 3600
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Headers: Authorization_Code
Access-Control-Allow-Headers: User_Credentials
Access-Control-Allow-Headers: Client_Credentials
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 14 Mar 2016 11:19:42 GMT Raw JSON
JSON Response Body -
{ "id":78, "userId":"3465434567", "coachId":null,
"name":"XDCDSC", "dob":null, "email":"puneetpandey37#gmail.com",
"imageURL":"https://lh5.googleusercontent.com/-TcTQeitAvag/AAAAAAAAAAI/AAA/4pamurzO1a4/photo.jpg",
"gender":null, "userPhysic":null, "userTypeId":1,
"dietitanId":null, "alternateEmailId":null,
"yearsOfExperience":null, "lastExperience":null,
"languagesKnown":null, "aboutYourself":null,
"coreCompetence":null, "fieldOfWork":null, "userAddresses":[
{
"id":1,
"userId":78,
"locationId":1,
"address":"EC",
"landmark":"Near BN",
"phoneNumber":null,
"addressType":"Home"
} ], "phoneNumbers":[
] }

The response had HTTP status code 401.
Your server needs authentification for the Preflight Request, but the client removes credentials as CORS specification says:
Otherwise, make a preflight request. Fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag and the block cookies flag set, using the method OPTIONS, and with the following additional constraints:
Include an Access-Control-Request-Method header with as header field value the request method (even when that is a simple method).
If author request headers is not empty include an Access-Control-Request-Headers header with as header field value a comma-separated list of the header field names from author request headers in lexicographical order, each converted to ASCII lowercase (even when one or more are a simple header).
Exclude the author request headers.
Exclude user credentials.
Exclude the request entity body.
You have to change your server, to allow anonymous access of Preflight Request.

Related

Angular with Java backend return CORS error

I´m trying to connect a Angular web to Java backend. For do this i use different endpoints. Return
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
I try adding proxy.conf.json like this in angular
{
"/URL/*": {
"target": "ENDPOINT",
"secure": false,
"changeOrigin": true
}
}
I try too modify .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
No works.
So: What´s is the properly way to abble CORS in angular endpoints?
UPDATE
httpOptions in angular
const httpOptions = {
headers: new HttpHeaders({
Authorization: "Token " + localStorage.getItem("token")
})
};
Welcome to the shitty world of modern Browsers :-)
If you use a Authorization header your Browser will perform a preflight request to check if your Browser has not been messed with via your Website and check the response. In particular, he will check if Access-Control-Allow-Origin is valid and for requests containing a Authorization header that means that a wildcard (*) is not valid! To make a Backend CORS-able you must allow the Origin of the request as a explicit Access-Control-Allow-Origin which leads many Backend developers to simply take the value of the Origin request header and put it into the Access-Control-Allow-Origin response header.
So when your Browser requests the Backend during a preflight, your Backend has to respond similar to
Access-Control-Allow-Origin: <The requesting Origin must be included>
Access-Control-Allow-Headers: origin, x-requested-with, content-type, authorization
Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
More on this can be found on Mozilla's page on CORS: https://developer.mozilla.org/de/docs/Web/HTTP/CORS

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.

CORS response headers not shown when using #CrossOrigin

I have created a basic GET endpoint, and attempted to allow CORS. However, the expected headers aren't returned in the response body, and I couldn't find what I'm doing wrong here.
GET method in my REST controller:
#CrossOrigin(
allowCredentials = "true",
origins = "*",
allowedHeaders = {
"Access-Control-Allow-Origin",
"Access-Control-Allow-Headers",
"Access-Control-Max-Age",
"Access-Control-Allow-Methods",
"Content-Type"})
public String test() {
return "test";
}
When I send a request here, the response headers are as follows:
Content-Length: 4
Content-Type: text/html;charset=UTF-8
Date: Mon, 13 May 2019 19:33:11 GMT
I'm hoping to add the headers to this response, i.e.:
Content-Length: 4
Content-Type: text/html;charset=UTF-8
Date: Mon, 13 May 2019 19:33:11 GMT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Max-Age, Access-Control-Allow-Methods, Content-Type
Access-Control-Allow-Origin: *
Any help would be greatly appreciated.
Ahh, I see - these headers are only added for cross-origin requests. When I set the origin in the request headers, the response headers are added as expected.

Spring security POST method throwing 403 error

I am building a user registration form. I have POST endpoint for registration and I am able to successfully register.
I have another endpoint called /invalid-token which is also mappped to POST mapping. I have added both of the endpoints to permitAll rules as below:
http.authorizeRequests()
.antMatchers(
"/register",
"/confirm",
"/invalid-token",
"/registration-success")
.permitAll()
.anyRequest()
.authenticated();
When I make a POST request to the invalid-token from the browser, I am getting a 403. I am not understanding where I am going wrong.
Response Status:
General:
Request URL: http://localhost:8081/invalid-token
Request Method: POST
Status Code: 403
Remote Address: [::1]:8081
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Tue, 23 Apr 2019 05:14:30 GMT
Expires: 0
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
I would recommend you to follow standard API definitions when defining micro services.
Issue could be the pattern you have defined i.e. /invalid-token
CSRF disable worked because in your API URL the pattern /invalid-token has special character which I guess allowed by SpringSecurity.
When CSRF is enabled than some how - is causing spring security to mark it as 403.
You can try with pattern /invalid/token and even with CSRF enabled and it should get required behaviour.

Restlet: cookie is not sent to all pages of the domain/app

I have a restlet resource that authenticates a person and sets a cookie with a key:
#Post("json")
public Representation login(String json) {
// validate user credentials ...
getResponse().getCookieSettings().add(new CookieSetting(1, "k", key));
getResponse().getCookieSettings().add(new CookieSetting(1, "p", person.getURI()));
return new StringRepresentation(response.toString(), MediaType.APPLICATION_JSON);
}
When I invoke the URL associated with the login() method, everything seems to be fine. The cookies seem to be returned correctly in the response, and if I already have received cookies before, they are sent to the server:
Remote Address: 127.0.0.1:8000
Request URL: http://127.0.0.1:8000/api/person
Request Method: POST
Status Code: 200 OK
Request Headers
Accept: undefined
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,pt-PT;q=0.6,pt;q=0.4,es-419;q=0.2,es;q=0.2,en-GB;q=0.2
Connection: keep-alive
Content-Length: 42
Content-Type: application/json
Cookie: k="546f71445bf1bacd60a3f715d0250267"; p="http://compflow.pt/flowOntology/admin"
Host: 127.0.0.1:8000
Origin: http://127.0.0.1:8000
Referer: http://127.0.0.1:8000/job
X-Requested-With: XMLHttpRequest
Response Headers
Accept-Ranges: bytes
Content-Length: 46
Content-Type: application/json; charset=UTF-8
Date: Tue, 01 Jul 2014 15:05:13 GMT
Server: Restlet-Framework/2.1.7
Set-Cookie: k=546f71445bf1bacd60a3f715d0250267
Set-Cookie: p=http://compflow.pt/flowOntology/admin
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
The invocation to http://127.0.0.1:8000/api/person is performed through an AJAX call using JQuery as follows:
$.ajax({
url: '/api/person',
type:'POST',
accepts : "application/json",
contentType : "application/json",
processData : false,
dataType : "text",
data: JSON.stringify(data),
success: function (data) {
data = JSON.parse(data);
sessionStorage["userData"] = JSON.stringify(data.data);
if(callback) callback();
},
error: function(data) {
$('.alert-error').text(data).show();
}
});
However, if I try to perform a GET (directly through the browser) to the address http://127.0.0.1:8000/job, the cookies are not sent. The Cookie header is not set in the request.
Since it is not a cross-domain request and no restrictions are set regarding the path and domain of the cookies (I have tried setting them to "/" and "127.0.0.1" to no avail), I have no ideas left regarding what may be causing this issue. I would greatly appreciate all the help you can give me.
Curiously, the kind of HTTP server connector changes the behavior of the code. I've entered an issue for that (https://github.com/restlet/restlet-framework-java/issues/927).
As a workaround, I suggest you to precise the path, as follow:
getCookieSettings().add(new CookieSetting(0, "k", key, "/", null));
NB: inside a ServerResource; you can use the shortcut "getCookieSettings()", instead of "getResponse().getCookieSettings()".

Categories