CORS Enabled

From W3C Wiki
Revision as of 13:59, 8 November 2012 by Tbroyer (Talk | contribs)

Jump to: navigation, search

What is CORS about?

CORS is a specification that enables truly open access across domain boundaries.

Why is CORS important?

Currently, client-side scripts (e.g., JavaScript) are prevented from accessing much of the Web of Linked Data due to "same origin" restrictions implemented in all major Web browsers.

While enabling such access is important for all data, it is especially important for Linked Open Data and related services; without this, our data simply is not open to all clients.

If you have public data which doesn't use require cookie or session based authentication to see, then please consider opening it up for universal JavaScript/browser access.

For CORS access to anything other than simple, non auth protected resources please see this full write up on Cross Origin Request Security.

How can I participate?

Granting JavaScript clients basic access to your resources simply requires adding one HTTP Response Header, namely:

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Origin: http://example.com:8080
 Access-Control-Allow-Origin: http://example.com:8080 http://blah.example.com http://foo.example.com

The asterisk wild-card permits scripts hosted on any site to load your resources; listing one or more specific <base URI> will permit scripts hosted on the specified site(s) -- and no others -- to load your resources.

This is compatible with both XHR XMLHttpRequest and XDR XDomainRequest, and is supported by all the major Web browsers.

(Note that to grant access to multiple specific sites, each and every such site's Origin request header must be included in the Access-Control-Allow-Origin response header.)

At the HTTP Server level...

Security Note: The examples given below assume a wild-card '*' domain for the Access-Control-Allow-Origin header. This is provided to simplify basic use of CORS, practically meaning "I don't care how this is used." In an intranet setting, this could lead to leakage of data beyond the intranet and therefore should be avoided. In a production setting, you should take advantage of the full features of the CORS specification to make sure it does express your actual security policy. That said, in a typical Open Data situation, the wild-card can be an appropriate use of CORS.

For Apache

Apache can be configured to expose this header using mod_headers. This is enabled by default in Apache, however you may want to ensure it's enabled in your deployment by running the following command:

 a2enmod headers

To expose the header, you can add the following line inside <Directory>, <Location>, and <Files> sections, or within an .htaccess file.

 <IfModule mod_headers.c>
   Header set Access-Control-Allow-Origin "*"
 </IfModule>

You can use add rather than set, but be aware that add can add the header multiple times, so it's generally safer to use set.

Finally, you may need to reload Apache to make sure your changes have been applied.

For nginx

CORS can be enabled using the Headers core module which is compiled into nginx by default:

 add_header Access-Control-Allow-Origin *;

For IIS7

Merge this into the web.config file at the root of your application / site:

  <?xml version="1.0" encoding="utf-8"?>
  <configuration>
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </configuration>

If you don't have a web.config file already, or don't know what one is, just create a new file called "web.config" containing the snippet above.

For IIS6

  1. Open Internet Information Service (IIS) Manager
  2. Right click the site you want to enable CORS for and go to Properties
  3. Change to the HTTP Headers tab
  4. In the Custom HTTP headers section, click Add
  5. Enter Access-Control-Allow-Origin as the header name
  6. Enter * as the header value
  7. Click Ok twice

For Jetty (7 and above)

Jetty 7 (starting with 7.0.0.RC2 to be exact) ships with a CrossOriginFilter. More information...

Include the jetty-servlets JAR into you WEB-INF/lib and merge this into your WEB-INF/web.xml:

   <filter>
       <filter-name>cross-origin</filter-name>
       <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
   </filter>
   <filter-mapping>
       <filter-name>cross-origin</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>

The CrossOriginFilter can also be configured in the webdefault.xml to apply to all applications; the jetty-servlets JAR is already bundled within Jetty for this use-case.

It's a simple servlet filter and should be usable in other servlet containers, such as Tomcat, JBoss AS or Glassfish.

For OpenLink Virtuoso (Basic Web Sites, Linked Data Spaces, SPARQL Endpoints, and otherwise)

  1. Open up the Virtuoso Conductor's Virtual Home and Directory Admin UI
  2. Set the CORS options on your target virtual directory via the Cross-Origin Resource Sharing field by entering: " * " or a space-delimited list of HTTP server URIs, e.g.,
    http://example.com:8080 http://blah.example.com http://foo.example.com
  3. Optionally hatch Reject Unintended CORS check-box, and unmatched Origins (after any header re-writing by the application itself) will be receive an empty response.

At the Web Application level...

If you can't configure the HTTP server, you can still add the necessary header through various hosting environments.

In ASP.NET

Add the the following line to your source pages.

 Response.AppendHeader("Access-Control-Allow-Origin", "*");

This is compatible with IIS6, IIS7 Classic Mode, and IIS7 Integrated Mode.

In Plack Scripts

Install the Plack::Middleware::CrossOrigin module and enable it with:

    enable 'CrossOrigin', origins => '*';

There are also more advanced options available.

In CGI Scripts

Just output the line

Access-Control-Allow-Origin: *


as part of your CGI script's headers.

With Perl, using CGI.pm
  print header(
    -type                        => 'text/turtle',
    -content_location            => 'mydata.ttl',
    -access_control_allow_origin => '*',
    );
With Python
  print "Content-Type: text/turtle"
  print "Content-Location: mydata.ttl"
  print "Access-Control-Allow-Origin: *"
  print

In ExpressJS

In your ExpressJS app on nodejs, do the following with your routes

  app.all('/', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next()
  });
  app.get('/', function(req, res, next) {
    // Handle the get for this route
  });
  app.post('/', function(req, res, next) {
    // Handle the post for this route
  })

In PHP

Add the following line to your PHP scripts --

 <?php
 header("Access-Control-Allow-Origin: *");

As with all uses of the PHP header function, this must be done before any output has been sent from the server.

Via VSP (Virtuoso Server Page)

You can implement CORS checking through Virtuoso's built-in HTTP functions http_request_header() and http_header(). This will work with any version of Virtuoso. For example --

<?vsp 
   IF (http_request_header (lines, 'Origin', NULL) = 'http://host.org')
     {
         http_header ('Access-Control-Allow-Origin: http://host.org\r\n');
     }
  ELSE 
     {
        RETURN;
     }
-- Additional code here ---
?>

In Java servlets

Simply add a header to your HttpServletResponse by calling addHeader:

 response.addHeader("Access-Control-Allow-Origin", "*");

Who is doing it already?

Platforms

Services

SPARQL Endpoints

Toolkits

Data Sets

Ontologies

Who still needs to get on board?

Join our effort to enable CORS on the Web by requesting that your favorite website implement it. You can follow the progress of requests sent to popular services here. Don't hesitate to join the conversations linked here, and to list the requests you've made yourself!

Who's not willing to get on board?