Search code examples
phpauthenticationbasic-authentication

Basic Auth Response for wrong User


I do have a working PHP basic auth code for 1 user per domain. But I don't get it working with 2 different users on 1 domain in the same client (calendars: thunderbird-lightning, mac calendar).

Here is my example:

$auth = null;
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
    $auth = login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], 'basic');
    if ($auth->getUser() != $theCorrectUser) {
        header('WWW-Authenticate: Basic realm="Login"');
        header('Content-type: text/calendar; charset=utf-8', true);
        http_response_code(403);
        echo 'wrong user';
        exit;
    }
}
if (!$auth) {
    header('WWW-Authenticate: Basic realm="Login"');
    header('Content-type: text/calendar; charset=utf-8', true);
    http_response_code(401);
    echo 'invalid user';
    exit;
}
// still there? -> user is logged in and correct

Example Links:

The idea:

  • if there is no Basic Auth or it's wrong -> HTTP Response 401
  • if the Basic Auth is right, but the user has no access to the source -> HTTP Response 403

The Problem:

  • when I send 403, the client will not ask the user to input another username+passwort
  • if I would also send a 401 for wrong user attempts, the client will "logout" all users for this domain

What's the trick having multiple basic-auth users at once in the same client? :)


Solution

  • as mentioned from @Barmar in the comments above or in a PHP documentation comment the solution is to use different realms. I added an user-specific realm.

    working example:

    $auth = null;
    if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
        $auth = login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], 'basic');
        if ($auth->getUser() != $theCorrectUser) {
            header('WWW-Authenticate: Basic realm="Login for user '.$auth->getUserIdent().'"');
            header('Content-type: text/calendar; charset=utf-8', true);
            http_response_code(403);
            echo 'wrong user';
            exit;
        }
    }
    if (!$auth) {
        header('WWW-Authenticate: Basic realm="Login for user '.$auth->getUserIdent().'"');
        header('Content-type: text/calendar; charset=utf-8', true);
        http_response_code(401);
        echo 'invalid user';
        exit;
    }
    // still there? -> user is logged in and correct