I have created an AWS HTTP API gateway. It maps to my lambda function.
I have enabled JWT type authorization on my routes, it uses a cognito pool.
Calling the API from insomnia/postman with the auth token added works and returns as expected.
The CORS policy for the HTTP API is set in the following way:
x-amazon-apigateway-cors:
allowMethods:
- "DELETE"
- "GET"
- "HEAD"
- "OPTIONS"
- "PATCH"
- "POST"
- "PUT"
allowHeaders:
- "*"
- "accept"
- "access-control-allow-origin"
- "authorization"
- "content-type"
exposeHeaders:
- "*"
- "accept"
- "access-control-allow-origin"
- "authorization"
- "content-type"
maxAge: 600
allowCredentials: true
allowOrigins:
- "http://localhost:19006/"
I see the preflight OPTIONS request to my URL, and I also see that it gets 401 response for it, and doesn't return the set headers as above.
How can I enable cors while also having the cognito JWT type authorization?
Edit: I am sending the request from react side this way:
fetch('<URL>', { credentials: 'include', headers: { Authorization: 'Bearer ' + token,'content-type': 'text/html' }, redirect: 'follow', mode: 'cors' })
As far as I'm aware react doesn't send an authorisation header to the OPTIONS pre flight request. So if you've added authorisation to this path it will always respond with a 401. The OPTIONS resource should not have authorisation placed on it.
Related
I have a problem with my cors policy between my backend (API Rest in .NET Core 6) and my frontend (in ReactJS), the thing is that in my backend I have the following configuration:
In appsetings.json:
"AllowedHosts": "mywebsite.com"
In Program.cs:
services.AddCors(options =>
{
options.AddPolicy(name: "mycors", builder =>
{
builder.WithOrigins("mywebsite.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
app.UseCors("mycors");
This configuration doesn't work when I'm trying to fetch a post request to my API, but if I change the AllowedHosts to "AllowedHosts": "*" it works. I don't understand why I can't allow just to my frontend website.
Additional information, my post request has these parameters:
method: 'POST'
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
redirect: 'follow',
referrerPolicy: 'no-referrer',
headers: { 'Content-Type': 'application/json' },
body: //My parameters
The console error is:
Access to fetch at 'mybackendpostmethod' from origin 'myfronturl.com' has been blocked by CORS policy: 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.
I solved putting my api that return as follows
Ext.Ajax.request({
url: 'https://dev-516799.oktapreview.com/api/v1/users?limit=200',
method: 'GET',
Accept: 'application/json',
'Access-Control-Allow-Origin': '*',
headers: {
'Authorization': 'SSWS Token'
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
//'Access-Control-Allow-Methods': 'GET'
},
scope: this,
cleanup: function () {
view.setLoading(false);
},
success: function (response) {
}
But I am getting error as "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource"
Access-control: Allow-Origin headers are a security feature that has to be enabled in the reply from the server, not in the request to the server.
Examples: ExtJS - Adding headers to AJAX store
In your case, you are at the mercy of Okta. They have some APIs that support CORS if you provide them with the allowed URLs, and others that don't. You cannot access Okta APIs directly from your JavaScript code unless the APIs are marked as CORS-enabled and you have added your URL to the list of CORS-enabled URLs in the Okta admin panel. If you need unmarked APIs or access from arbitrary URLs, you may have to create a wrapper in your own server backend that relays the requests from your frontend to the Okta server.
I have implemented a backend with an Apache server with AMI from AWS and Laravel. For authentication I use the JWT Auth plugin.
My frontend is build with AngularJS. Before using the authentication everything worked fine. When I try to authenticate the user with an authorization header I get a CORS Preflight error. I use the following call from my AngularJS application:
delete $http.defaults.headers.common['X-Requested-With'];
$http.defaults.headers.common.Accept = "text/plain";
$http({
url: 'http://MYURL',
method: "GET",
headers: {
'Access-Control-Allow-Headers': 'Authorization, Content-Type, Accept',
'Content-Type' : 'text/plain',
'Authorization': 'Bearer '+token,
}
})
In my Laravel backend I used the following configuration:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Authorization, Content-Type");
This is the response from the OPTIONS call:
This is the error I get in Google Chrome:
Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
Any ideas on this issue? Do I have to configure this within Angular, Laravel or my httpd.conf?
EDIT:
I added it as a global Middleware and in the app.php as service provider.
The configuration looks like this:
return [
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedHeaders' => ['Authorization, Content-Type'],
'allowedMethods' => ['*'],
'exposedHeaders' => [],
'maxAge' => 0,
'hosts' => [],
];
But I have no idea if it works correctly.
Have you considered using a plugin for managing CORS setup like this one?
It appears that the list of headers you allow on the server side (Authorization, Content-Type) is not the same as the list of headers being sent by the request (Authorization, Content-Type, Accept). It could be that the front end is asking for permissions that you aren't allowing on the back end.
On my C# web api I have cors enabled i.e.
[EnableCors(origins: "*", headers: "*", methods: "*")]
and then in my angular js site I am calling post API as such
authService.login = function (credentials) {
return $http
.post(WEB_CONFIG.login, credentials)
.then(function (res) {
Session.create(res.data.Email, res.data.Roles,res.data.Username);
return res.data.user;
});
};
The angular site is making the request from localhost:9000, and the API is located at localhost
getting the error
XMLHttpRequest cannot load http://localhost/mysite/api/user/login. 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:9000' is therefore not allowed access.
Why am I getting this error with Cors enabled ?
Try this configuration.
cors:
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
I'm using angularJS to call a restfull API in symfony 2.
My angularJS app url is angular.me.dev
My symfony2 api url is api.me.dev
I followed this tutorial to make my restfull api.
The problem is when I try to call this api
$http.({
method: 'GET',
url: 'http://api.me.dev/api/articles',
headers: {
'Authorization': 'Bearer ' + token
}
})
An error occured: (here on google chrome):
XMLHttpRequest cannot load http://api.me.dev/api/articles. Response for preflight has invalid HTTP status code 405
(and on on firefox):
The Same Origin Policy disallows reading the remote resource
what did I find about this ?
AngularJS Sends OPTIONS request instead of POST
AngularJS performs an OPTIONS HTTP request for a cross-origin resource
Then I decide to allow headers, origin, ... on my server like this:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Methods "PUT, DELETE, POST, GET, OPTIONS"
Header always set Access-Control-Allow-Headers "*"
No change
I add to AngularJS
#coffee script
app.config ['$httpProvider', ($httpProvider) ->
$httpProvider.defaults.useXDomain = true
delete $httpProvider.defaults.headers.common['X-Requested-With']
]
Then I decided to install NelmioCorsBundle in my symfony api but I didn't see any change.
Finally, I notice a call works
$http.({
method: 'GET',
url: 'http://api.me.dev/api/articles',
})
Here the call return a 401 response (good, i need to be logged)
$http.({
method: 'GET',
url: 'http://api.me.dev/public/api/users',
})
Here I have a call doesn't need authorization, it works.
I found only when I remove headers it works, and when I had any headers (content-type or authorization for example) an error occured.
Can anyone help me ? thanks !
Ok, my bad.
I said NelmioCors seems not working but i did something wrong.
I try again with nelmio cors bundle, using this configuration.
nelmio_cors:
paths:
'^/':
allow_origin: ['http://angular.me.dev']
allow_headers: ['Authorization', 'X-Requested-With', 'Content-Type', 'Accept', 'Origin', 'X-Custom-Auth']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
max_age: 3600
It's working !
NelmioCorsBundle resolve the problem.
https://github.com/nelmio/NelmioCorsBundle