Restricting public access to an entire instance, outside user account system


#1

Occasionally it is desirable to lock down access to an entire site behind a username+password, such that not even the usual login/register forms and top-level site branding is visible to the public. This is commonly the case for staging instances, internal versions of client sites, or deprecated sites that you still want a small set of users to be able access on a public server, but without exposing any branding publically

Create a file under php-config/Site.config.d with a snippet like this to apply an HTTP-level lockdown:

<?php
Site::$onBeforeScriptExecute = function() {
    // exempt some roots from the added auth layer
    if (
        Site::$requestPath[0] == 'develop' // don't double-wrap developer access
        || Site::$requestPath[0] == 'google1234567.html' // allow webmaster tools validation
    ) {
        return;
    }

    // skip the added auth layer if a staff session is present
    if (!empty($GLOBALS['Session']) && $GLOBALS['Session']->hasAccountLevel('Staff')) {
        return;
    }

    // apply any HTTP username/password requirement you like
    if (
        empty($_SERVER['PHP_AUTH_USER'])
        || empty($_SERVER['PHP_AUTH_PW'])
        || $_SERVER['PHP_AUTH_USER'] != 'internal'
        || $_SERVER['PHP_AUTH_PW'] != 'Ej46DJft1T' // generate your own!
    ) {
        header('WWW-Authenticate: Basic realm="Private"'); // leak no details
        header('HTTP/1.0 401 Unauthorized');
        die('Access denied');
    }
};

Additionally, you might wrap this whole chunk in an if condition that bypasses it for or restricts it to certain hostnames or instance IDs, or use a simple array structure to support multiple username+password combinations.