Server-Side Access Control

  • Revision slug: Server-Side_Access_Control
  • Revision title: Server-Side Access Control
  • Revision id: 53939
  • Created:
  • Creator: aruner
  • Is current revision? No
  • Comment 47 words added

Revision Content

Firefox 3.1 implements the W3C Access Control specification.  As a result, Firefox 3.1 sends specific HTTP headers for cross-site requests initiated from within XMLHttpRequest (which in Firefox 3.1 and beyond can be used to invoke different domains) and for cross-site font downloads.  It also expects to see specific HTTP headers sent back with cross-site responses.  An overview of these headers, including sample JavaScript code that initiates and processes requests, as well as a discussion of each header, can be found here (HTTP Access Control).  The HTTP Access Control article should be read as a companion article to this one.  This article covers processing Access Control Requests and formulating Access Control Responses in PHP.  The target audience is thus server programmers or administrators.  Although the code samples shown here are PHP, similar concepts apply for ASP.net, Perl, Python, Java, etc.; in general, any server-side programming environment that processes HTTP requests and dynamically formulates HTTP responses.

Simple Cross-Site Requests

Simple Access Control Requests are initiated when:

  • An HTTP/1.1 GET or a POST is used as request method.  In the case of a POST, the Content-Type of the request body is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.
  • No custom headers are sent with the HTTP Request (such as X-Modified, etc.)

In this case, responses can be sent back based on some considerations.

  • If the resource in question is meant to be widely accessed (just like any HTTP resource accessed by GET), than sending back the Access-Control-Origin: * header will be sufficient, unless the resource needs credentials such as Cookies and HTTP Authentication information.
  • If the resource should be kept restricted based on requester domain, OR if the resource needs to be accessed with credentials (or sets credentials), then filtering by the request's ORIGIN header may be necessary, or at least echoing back the requester's ORIGIN (e.g. Access-Control-Origin: http://arunranga.com).  Additionally, the Access-Control-Allow-Credentials: true header will have to be sent.  This is discussed in a subsequent section.

The section on Simple Access Control Requests shows you the header exchanges between client and server.  Here is a PHP code segment that handles a Simple Request:

<?php
// We'll be granting access to only the arunranga.com domain which we think is safe to access this resource as application/xml

if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com")
{
 
    header('Access-Control-Allow-Origin: http://arunranga.com');
    header('Content-type: application/xml');
    readfile('arunerDotNetResource.xml');
}
else
{    
header('Content-Type: text/html');
echo "<html>";
echo "<head>";
echo "   <title>Another Resource</title>";
echo "</head>";
echo" <body>
    <p>This resource behaves two-fold:";
echo "<ul>
        <li>If accessed from <code>http://arunranga.com</code> it returns an XML document</li>";
echo  " <li>If accessed from any other origin including from simply typing in the URL into the browser's address bar,";
echo "you get this HTML document"</li>", 
    "</ul>",
"</body>",
"</html>";
}
?>

 The above checks to see if the ORIGIN header sent by the browser (obtained through $_SERVER['HTTP_ORIGIN']) matches 'http://arunranga.com'.  If yes, it returns Access-Control-Allow-Origin: http://arunranga.com

Revision Source

<p>Firefox 3.1 implements the <a class="external" href="http://dev.w3.org/2006/waf/access-control/" title="http://dev.w3.org/2006/waf/access-control/">W3C Access Control specification</a>.  As a result, Firefox 3.1 sends specific HTTP headers for cross-site requests initiated from within <code><a class="internal" href="/en/XMLHttpRequest" title="En/XMLHttpRequest">XMLHttpRequest</a></code> (which in Firefox 3.1 and beyond can be used to invoke different domains) and for cross-site <a class="external" href="http://www.webfonts.info/wiki/index.php?title=%40font-face_support_in_Firefox" title="http://www.webfonts.info/wiki/index.php?title=@font-face_support_in_Firefox">font downloads</a>.  It also expects to see specific HTTP headers sent back with cross-site responses.  An overview of these headers, including sample JavaScript code that initiates and processes requests, as well as a discussion of each header, <a class="internal" href="/En/HTTP_access_control" title="En/HTTP Access Control">can be found here (HTTP Access Control).</a>  The <a class="internal" href="/En/HTTP_access_control" title="En/HTTP access control">HTTP Access Control</a> article should be read as a companion article to this one.  This article covers processing <strong>Access Control Requests</strong> and formulating <strong>Access Control Responses</strong> in PHP.  The target audience is thus server programmers or administrators.  Although the code samples shown here are PHP, similar concepts apply for ASP.net, Perl, Python, Java, etc.; in general, any server-side programming environment that processes HTTP requests and dynamically formulates HTTP responses.</p>
<h3>Simple Cross-Site Requests</h3>
<p><a class="internal" href="/En/HTTP_access_control#Simple_Requests" title="En/HTTP access control#Simple Requests">Simple Access Control Requests</a> are initiated when:</p>
<ul> <li>An HTTP/1.1 <code>GET</code> or a <code>POST</code> is used as request method.  In the case of a POST, the Content-Type of the request body is one of <code>application/x-www-form-urlencoded</code>, <code>multipart/form-data</code>, or <code>text/plain.</code></li> <li>No custom headers are sent with the HTTP Request (such as <code>X-Modified</code>, etc.)</li>
</ul>
<p>In this case, responses can be sent back based on some considerations.</p>
<ul> <li>If the resource in question is meant to be widely accessed (just like any HTTP resource accessed by GET), than sending back the <code>Access-Control-Origin: *</code> header will be sufficient, <strong>unless</strong> the resource needs credentials such as Cookies and HTTP Authentication information.</li> <li>If the resource should be kept restricted based on requester domain, <strong>OR</strong> if the resource needs to be accessed with credentials (or sets credentials), then filtering by the request's <code>ORIGIN</code> header may be necessary, or at least echoing back the requester's <code>ORIGIN</code> (e.g. <code>Access-Control-Origin: <a class=" external" href="http://arunranga.com" rel="freelink">http://arunranga.com</a></code>).  Additionally, the <code>Access-Control-Allow-Credentials: true</code> header will have to be sent.  This is discussed in a <a class="internal" href="/#Credentialed_Request" title="#Credentialed Request">subsequent section</a>.</li>
</ul>
<p>The section on <a class="internal" href="/En/HTTP_access_control#Simple_Requests" title="En/HTTP access control#Simple Requests">Simple Access Control Requests</a> shows you the header exchanges between client and server.  Here is a PHP code segment that handles a Simple Request:</p>
<pre class="brush: php">&lt;?php
// We'll be granting access to only the arunranga.com domain which we think is safe to access this resource as application/xml

if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com")
{
 
    header('Access-Control-Allow-Origin: http://arunranga.com');
    header('Content-type: application/xml');
    readfile('arunerDotNetResource.xml');
}
else
{    
header('Content-Type: text/html');
echo "&lt;html&gt;";
echo "&lt;head&gt;";
echo "   &lt;title&gt;Another Resource&lt;/title&gt;";
echo "&lt;/head&gt;";
echo" &lt;body&gt;
    &lt;p&gt;This resource behaves two-fold:";
echo "&lt;ul&gt;
        &lt;li&gt;If accessed from &lt;code&gt;http://arunranga.com&lt;/code&gt; it returns an XML document&lt;/li&gt;";
echo  " &lt;li&gt;If accessed from any other origin including from simply typing in the URL into the browser's address bar,";
echo "you get this HTML document"&lt;/li&gt;", 
    "&lt;/ul&gt;",
"&lt;/body&gt;",
"&lt;/html&gt;";
}
?&gt;
</pre>
<p> The above checks to see if the<code> ORIGIN</code> header sent by the browser (obtained through $_SERVER['HTTP_ORIGIN']) matches '<a class=" external" href="http://arunranga.com" rel="freelink">http://arunranga.com</a>'.  If yes, it returns <code>Access-Control-Allow-Origin: <a class=" external" href="http://arunranga.com" rel="freelink">http://arunranga.com</a></code></p>
Revert to this revision