HTTP Authentifizierungsklasse
HTTP authentication class
This class manages user HTTP authentication, which is a common, safe and simple way of user
login. The instance throws an exception if the user or password is wrong. The password is
given with a .htaccess-like hash (using crypt()
). The static function createPassword()
can be used to create a compatible password. Let's take a look how to use the class:
Diese Klasse übernimmt die HTTP Authentifikation (login wie .htaccess). Das Objekt wirft
eine Exception, wenn User oder Passwort falsch ist. Das Password wird als .htaccess-kompatible
Hash-Summe (crypt()
) übergeben. Die statische Funktion createPassword()
kann zur
Generierung kompatibler Passworte genutzt werden. Hier ein Anwendungsbeispiel:
Sample source code
Anwendungsbeispiel
<?php
// Example users
$users = array(
'user1' => HttpAuthentication::createPassword('pass1'),
'user2' => crypt('pass2')
);
// Create instance
$auth = new HttpAuthentication($users);
// Add a user after the object was instanciated
$auth->addUser('user3', HttpAuthentication::createPassword('pass3'));
// Test if the authentication is ok
try {
$auth->requireAuthentication();
print "Auth succeeded";
} catch(Exception $e) {
print "Auth failed: " . $e->getMessage();
}
?>
Class source code
And here the class source code. If you use autoloading, you should move the HttpAuthenticationException
class to a separate file.
Klassen-Quelltext
Und hier der Sourcecode der Klasse. Für Autoloading sollte die HttpAuthenticationException
in eine separate Datei verschoben werden.
<?php
/**
* Http authentication exception, thrown if the authentication fails
* @gpackage de.atwillys.sw.php.classes
* @author Stefan Wilhelm
* @copyright Stefan Wilhelm, 2008-2010
* @license GPL
* @version 1.0
*/
namespace sw;
class HttpAuthenticationException extends LException {
}
<?php
/**
* Http authentication wrapper with external user management. The registered
* users are passed in the constructor/function addUser in an associative array,
* where the keys are the user login names and the values the ENCRYPTED passwords.
* The encryption function is the UNIX crypt(). The static function createPassword()
* can be used as well. To activate the feature call
*
* try {
* HttpAuthentication::requireAuthentication();
* } catch(HttpAuthenticationException $e) {
* ...
* }
*
* @gpackage de.atwillys.sw.php.classes
* @author Stefan Wilhelm
* @copyright Stefan Wilhelm, 2008-2010
* @license GPL
* @uses HttpAuthenticationException
*/
require_once("HttpAuthenticationException.class.php");
namespace sw;
class HttpAuthentication {
/**
* List if users and passwords
* @var array
*/
private $users = array();
/**
* Login name of actual user
* @var string
*/
private $actualUser = null;
/**
* Returns a encrypted password from a plain text password
* @param string $unencrypted
* @return string
*/
public static function createPassword($unencrypted) {
return crypt($unencrypted);
}
/**
* Constructor with assoc array:
* keys are user names, values are crypt(passwords).
* @param array $users
*/
public function __construct(array $users=array()) {
foreach ($users as $key => $value) {
$this->addUser($key, $value);
}
}
/**
* Adds a user to the login list. throws Exception if user exists.
* @param string $loginName
* @param string $cryptedPassword
*/
public function addUser($loginName, $cryptedPassword) {
$loginName = strtolower($loginName);
if (isset($this->users[$loginName])) {
throw new HttpAuthenticationException('User ":user" already exists in login list', array(':user' => $loginName));
} else {
$this->users[$loginName] = $cryptedPassword;
}
}
/**
* Returns the current user.
* @return string
*/
public function getUser() {
if (is_null($this->actualUser)) {
$user = trim(strtolower($_SERVER['PHP_AUTH_USER']));
$auth = $_SERVER['PHP_AUTH_PW'];
if (empty($this->users[$user]) || trim($auth) == '' || crypt($auth, $this->users[$user]) != $this->users[$user]) {
$this->actualUser = '';
} else {
$this->actualUser = $user;
}
}
return $this->actualUser;
}
/**
* Throws an Exception if the user is not authorized
* and adds the WWW-Authenticate to signal the required
* auth to the browser.
*/
public function requireAuthentication() {
if ($this->getUser() == '') {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
if (trim($_SERVER['PHP_AUTH_USER']) == '' && trim($_SERVER['PHP_AUTH_PW']) == '') {
throw new HttpAuthenticationException('User did not enter data');
} else if (trim($_SERVER['PHP_AUTH_USER']) == '') {
throw new HttpAuthenticationException('User name not entered');
} else if (trim($_SERVER['PHP_AUTH_PW']) == '') {
throw new HttpAuthenticationException('User password not entered');
} else {
throw new HttpAuthenticationException('User entered wrong password (user=:user)', array(':user' => $_SERVER['PHP_AUTH_USER']));
}
}
}
}