-
Notifications
You must be signed in to change notification settings - Fork 0
Same Origin Policy
The Same Origin Policy built into web browsers is a security constraint that prevents scripts running in a web browser from making requests to URLs that have a different host or port than the running script came from. This constraint is overly restrictive in many scenarios, and specifically when a remote web data API is intended to be shared.
The Same Origin Policy applies to more than just JavaScript data APIs (for example: web fonts). However we're mostly concerned with web data APIs.
A common solution is to use either a server-level proxy or app-level proxy to ensure requests are actually always made to the same shared origin.
Update the app that is attempting to consume data from a remote source to instead consume from a local proxy endpoint (create a new Servlet in Java for example). This way, the request to the remote data API is actually coming from the local server side, and Same Origin no longer applies. This is probably the most flexible solution as it doesn't require the remote data API to do anything.
Often apps are hosted on the same origin behind a proxy for organizational purposes anyways, and in this case Same Origin is side-stepped, for example the many apps on ace.jlab.org. This scenario is slightly different than the in-app proxy approach (custom Servlet) in that it is often environment specific (production vs development). In production, relying on a shared HAProxy such as ace.jlab.org, is ideal (though not always possible for all related apps to be behind same proxy server). However, when developing and testing, this shared proxy scenario must be recreated, even for localhost.
Cross Origin Resource Sharing (CORS) is a way to bypass the same origin policy. However, it requires the remote host with the data API to participate, so doesn't apply if you don't control it and it isn't already set up to allow all origins / your origin.
Tomcat provides a built-in Servlet Filter for CORS. Wildfly/Undertow does not. Wildfly does come with RestEasy JAX-RS lib, which provides a ContainerRequestFilter, but that isn't compatible with a typical javax.servlet.Filter, so is only relevant if you are using JAX-RS for the endpoint you want to add CORS on. It's also possible to create your own custom Filter, or configure Wildfly/Undertow to send specific headers. However, take a look at the Tomcat CORS Filter Source and you'll see it isn't simple in the general case at least.
CORS is complicated and confusing, and keeping with security best practices restrictions should probably be lifted as narrowly as possible. This suggests the simplest thing of ALLOW_ORIGINS: *
is probably best avoided, in production at least. Or, if the special *
is used, should probably be applied very narrowly to specific paths, which complicates configuration.
There are other possible work-arounds as well, such as JSONP, but they're generally historical and not recommended.
The solution for working around the Same Origin Policy may differ in production vs development environments. In production, relying on a shared proxy server such as HAProxy is ideal. However, in this case, app development needs a separate solution. Possibilities:
- In development create a proxy endpoint directly in the app - then either use a container for the remote service or a fixed test server like acctest.acc.jlab.org. This is the most flexible as it doesn't matter where the remote is.
- You could spin up a Container with HAProxy or similar to allow sharing of the same port. Then for the remote service, either use a fixed server (such as acctest.acc.jlab.org) or spin up a Container. This has the advantage of most closely matching production, unless in production the two apps aren't behind the same proxy, in which case this would only solve development scenario.
- Configure a fixed server such as acctest.acc.jlab.org to use CORS allow from any. Could be done in production too, but that has security implications so seems less good.