Due to a change in requirements I had to implement a Dropwizard web service for communicating with our SAP Business One instance. This works great so far.
Furthermore, I need to make sure only authenticated clients are allowed to access the API. For accomplishing this I am using a JWT which is generated by an other already existing web service. For communicating with both web services I am using the same Aurelia fetch client.
Despite of having set the credentials option to include as well as returning the same values for the Access-Control-Allow-Origin and Access-Control-Allow-Credentials headers (http://127.0.0.1:9000 and true) the cookies are only sent to the web service that generates the JWT and not to the Dropwizard web service.
Below you can see the code for initialising the fetch client.
configuration.useStandardConfiguration()
.withDefaults
({
credentials: "include",
headers:
{
"Content-Type": "application/json;charset=utf-8"
}
});
Next, the following screenshot is shown in the developer console of Firefox when communicating to the go web service. The Cookie header is sent as expected.
However, when accessing the resource on the Dropwizard web service the cookie header is not sent.
In the first case the request is done from http://127.0.0.1 to http://127.0.0.1.
In the second case, the request is done from http://127.0.0.1 to http://192.168.16.22:8090, isn't it? This is a CORS request
Maybe this is your issue: Cross domain POST request is not sending cookie Ajax Jquery
You cannot set or read cookies on CORS requests through JavaScript. Although CORS allows cross-origin requests, the cookies are still subject to the browser's same-origin policy, which means only pages from the same origin can read/write the cookie.
Related
I'm working on an Angular web application. I need to make a POST request with a XML body to a server I don't have control over. The request needs an Authorization header. I tried the following:
Send the request directly: It only works when the application is served on http://localhost. Otherwise, the browser shows the following error: Access to XMLHttpRequest at 'server.com' from origin 'my-server.com' 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..
Use a browser extension that adds the missing header to responses: Unsafe, because the extension adds Access-Control-Allow-Origin: * to responses from all domains and that header allows requests from any domain.
Disable browser security: I ran Chrome using this command: chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security. Works when the application is running on a HTTPS server. However, it's unsafe, for the same reasons stated for the previous approach.
Use a third-party proxy: Works for a few requests, but the server blocks the proxy IP because the requests of all clients pass through the same proxy.
My project requires to bypass browser security without compromising security for non-related domains. My project also requires a different IP to be sent to the server by each client. That's required so that if a client overuses the feature, it won't affect other clients.
Is there a way I can add Access-Control-Allow-Origin: my-server.com to all responses or add the header only for a specific server? Is there a way I can redirect each request to a different IP so that the server won't block all my clients? Are there any other workarounds?
For protection of end users browsers block requests to other servers. Yes, you can have a cors browser extension but that is a temporary solution.
You need to set up an endpoint on your server 'my-server.com' to consume your web application post requests. From there you can communicate with the server you don't own and set up your proper auth headers ect.
For an Angular 1 app I am working on, cookie authentication is used. The problem is: when making OPTIONS calls, cookies are not sent and the server tries to redirect user to login again. Just wondering, whose "fault" is it? Server (Azure API Apps) or frontend? If frontend, how do I send cookies on OPTIONS call? I am using augular-resource and have configured it as below:
$httpProvider.defaults.withCredentials = true
The 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 … Exclude user credentials.
and also
The term user credentials for the purposes of this specification means cookies, HTTP authentication, and client-side SSL certificates that would be sent based on the user agent's previous interactions with the origin. Specifically it does not refer to proxy authentication or the Origin header.
So the client should not send cookies, and the server should be able to respond to the preflight request without requiring authentication to take place first.
I am using REST service, that is not in my control to modify.
The service have verification/login and many "data-retrive" endpoints.
I have been requested to create "Chrome packed app" that will use this REST service.
The limitations I have are:
Can't use sandboxed pages.
Can't use webview.
The problem:
Xhr requests ignore "Set-cookie" headers.
it's impossible to set cookies manually (Like there is no cookie api).
Ideas & research
I googled my way into XHR implementation using "chrome.socket", With no https support, since "chrome.socket" dose not support TLS.
Forge is a "Chrome-js" library that adds TLS support to the "chrome.socket"
Questions
Is there any way to Modify requests and response headers?
Is there any way to combine the XHR implementation using "chrome.socket" with Forge? (I don't really know the protocol or the original XHR implementation)
is it even reasonable to implement fake cookie API to manage the data from the headers?
You should look into using a Cross-Origin Resource Sharing (CORS) request. There is a good introduction here.
In particular, you will need to use withCredentials:
Standard CORS requests do not send or set any cookies by default. In
order to include cookies as part of the request, you need to set the
XMLHttpRequest’s .withCredentials property to true: [...]
Note that you will need the server's cooperation to do this:
In order for this to work, the server must also enable credentials by
setting the Access-Control-Allow-Credentials response header to
“true”.
Since you are always on Chrome, you could use the Fetch API instead of XMLHttpRequest2. In that case you would add the credentials option:
Should you want to make a fetch request with credentials such as
cookies, you should set the credentials of the request to “include”.
Both of these mechanisms will (1) support HTTPS and (2) manage cookies opaquely, i.e. they will not permit you to inspect the cookie data.
I am working on a Javascript library to create entities in Azure Storage Table. Luckily, Azure supports Cross-Origin Resource Sharing (CORS). CORS is disabled by default. Using Set Table Service Properties API it is possible enable it for specific domains and methods for a limited time.
Enabling CORS requires you to make a non-simple request: PUT request against https://<account-name>.table.core.windows.net/?restype=service&comp=properties with headers Authorization, x-ms-date, x-ms-version. When the library makes that HTTP request, browser sends a preflight request to the URL first. Preflight request always fails, because CORS is not enabled for that URL. The actual request fails, since preflight request is failed.
In that case, it seems not possible to enable CORS for Azure Storage services via client side javascript methods. Is that so? Is there anybody who worked on these APIs and managed to get it working?
NOTE: Having a proxy method is always an option (among others). We can create an API on the server side to enable CORS or even create entities without any client side execution (which doesn't require CORS at all). Client wouldn't need to make any cross domain request. However, I am not looking for that. I am more interested in solving the issue using client side capabilities only.
So I have an API deployed on a cloud service. For testing purposes I use various HTTP clients like Postman, Paw and RestClient to send request to my API and they all work just fine. But when I send an AJAX request from Browser either with jQuery, reqwset or any other, I get the following error:
XMLHttpRequest cannot load
{https://url/to/my/api/on/google-app-engine}. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8000' is therefore not allowed
access
So Why does an HTTP client work but browser throws an error? Is there any risk if I enable CORS on the server?
This is because of the “same origin” policy of web browsers. This prevents a script on one website to make requests on another website on your behalf.
Enabling CORS is safe as long as you trust the allowed client, which is probably not the case if the client is at localhost (since you have no control on localhost in general).
Special case: if there's no way for a client to perform changes on the server's domain, then it's safe to enable CORS in general.