| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- <?php
- /**
- * Security functions for user authentication and authorization.
- *
- * Usage example:
- * <code>
- * try {
- * $security = webbasics\Security::getInstance();
- *
- * // Authentication: can the origin of the request be trusted?
- *
- * // Verify that a user is logged in
- * $security->requireLogin();
- *
- * // Use a security token to verify that the request originated from a
- * // trusted page. This is recommended if, for example, the script makes
- * // changes to the database
- * $security->requireToken($_REQUEST['token']);
- *
- * // Authorization: is the user allowed to request this page?
- * $security->requireUserRole('admin');
- *
- * ...
- *
- * // Pass token to template so that it can be used in a submitted form or
- * // AJAX request
- * $template->set('token', $auth->generateToken());
- *
- * ...
- *
- * } catch(webbasics\AuthenticationFailed $e) {
- * die('Get lost hacker!');
- * } catch(webbasics\AuthorizationFailed $e) {
- * http_response_code(403);
- * die('You are not authorized to view this page.');
- * }
- * </code>
- *
- * Corresponding login controller example:
- * <code>
- * // Find the user using ActiveRecord (not part of the WebBasics library)
- * $user = User::first(array('username' => $_POST['username']));
- *
- * if (!$user)
- * die('Invalid username');
- *
- * // Current user is part of the
- * $security = webbasics\Security::getInstance();
- * $security->setUser($user);
- *
- * // Simple: use a plain password
- * if (!$security->attemptPassword($user, $_POST['password']))
- * die('Invalid password');
- *
- * // More secure: hash the password in a javascript function before
- * // submitting the login form
- * if (!$security->attemptPasswordHash($user, $_POST['password_hash']))
- * die('Invalid password');
- * </code>
- *
- * And the User model implementation used in the example above:
- * <code>
- * use ActiveRecord\Model;
- * use webbasics\AuthenticatedUser;
- * use webbasics\AuthorizedUser;
- *
- * class User extends Model implements AuthenticatedUser, AuthorizedUser {
- * function getUsername() {
- * return $this->username;
- * }
- *
- * function getPasswordHash() {
- * return $this->password;
- * }
- *
- * function getCookieToken() {
- * return $this->cookie_token;
- * }
- *
- * function setCookieToken($token) {
- * $this->update_attribute('cookie_token', $token);
- * }
- *
- * function getRegistrationToken() {
- * return $this->registration_token;
- * }
- *
- * function setRegistrationToken($token) {
- * $this->update_attribute('registration_token', $token);
- * }
- *
- * function getRole() {
- * return $this->role;
- * }
- * }
- * </code>
- *
- * @author Taddeus Kroes
- * @date 05-10-2012
- */
- namespace webbasics;
- require_once 'base.php';
- interface AuthenticatedUser {
- function getUsername();
- function getPasswordHash();
-
- function getCookieToken();
- function setCookieToken($token);
-
- function getRegistrationToken();
- function setRegistrationToken($token);
- }
- interface AuthorizedUser {
- function getRole();
- }
- class Security implements Singleton {
- const SESSION_TOKEN_NAME = 'auth_token';
- const SESSION_NAME_USERDATA = 'auth_userdata';
-
- private static $instance;
-
- private $user;
-
- static function getInstance() {
- if (self::$instance === null)
- self::$instance = new self;
-
- return self::$instance;
- }
-
- private function __construct() {}
-
- function generateToken() {
- $session = Session::getInstance();
- $token = sha1(self::generateRandomString(10));
- $session->set(self::SESSION_TOKEN_NAME, $token);
- return $token;
- }
-
- function requireToken($request_token) {
- if ($request_token != $this->getSavedToken())
- throw new AuthenticationFailed('invalid token "%s"', $request_token);
- }
-
- private function getSavedToken() {
- $session = Session::getInstance();
-
- if (!$session->isRegistered(self::SESSION_TOKEN_NAME))
- throw new AuthenticationError('no token saved in session');
-
- return $session->get(self::SESSION_TOKEN_NAME);
- }
-
- function sessionDataExists() {
- return Session::getInstance()->areRegistered(array(
- self::SESSION_TOKEN_NAME, self::SESSION_NAME_USERDATA));
- }
-
- function requireLogin() {
-
- }
-
- function requireUserRole() {
-
- }
-
- //function setUser(AuthenticatedUser $user) {
- // $this->user = $user;
- //}
-
- static function generateRandomString($length) {
- $CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUWXYZ01234567890123456789';
- $string = '';
-
- srand(time());
-
- for ($i = 0; $i < $length; $i++)
- $string .= $CHARS[rand(0, strlen($CHARS) - 1)];
-
- return $string;
- }
- }
- class AuthenticationError extends FormattedException {}
- class AuthenticationFailed extends FormattedException {}
- class AuthorizationError extends FormattedException {}
- class AuthorizationFailed extends FormattedException {}
- ?>
|