📄 security.php
字号:
<?php/* SVN FILE: $Id: security.php 7118 2008-06-04 20:49:29Z gwoo $ *//** * Short description for file. * * Long description for file * * PHP versions 4 and 5 * * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/> * Copyright 2005-2008, Cake Software Foundation, Inc. * 1785 E. Sahara Avenue, Suite 490-204 * Las Vegas, Nevada 89104 * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * * @filesource * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project * @package cake * @subpackage cake.cake.libs.controller.components * @since CakePHP(tm) v 0.10.8.2156 * @version $Revision: 7118 $ * @modifiedby $LastChangedBy: gwoo $ * @lastmodified $Date: 2008-06-04 13:49:29 -0700 (Wed, 04 Jun 2008) $ * @license http://www.opensource.org/licenses/mit-license.php The MIT License *//** * Short description for file. * * Long description for file * * @package cake * @subpackage cake.cake.libs.controller.components */class SecurityComponent extends Object {/** * The controller method that will be called if this request is black-hole'd * * @var string * @access public */ var $blackHoleCallback = null;/** * List of controller actions for which a POST request is required * * @var array * @access public * @see SecurityComponent::requirePost() */ var $requirePost = array();/** * List of controller actions for which a GET request is required * * @var array * @access public * @see SecurityComponent::requireGet() */ var $requireGet = array();/** * List of controller actions for which a PUT request is required * * @var array * @access public * @see SecurityComponent::requirePut() */ var $requirePut = array();/** * List of controller actions for which a DELETE request is required * * @var array * @access public * @see SecurityComponent::requireDelete() */ var $requireDelete = array();/** * List of actions that require an SSL-secured connection * * @var array * @access public * @see SecurityComponent::requireSecure() */ var $requireSecure = array();/** * List of actions that require a valid authentication key * * @var array * @access public * @see SecurityComponent::requireAuth() */ var $requireAuth = array();/** * List of actions that require an HTTP-authenticated login (basic or digest) * * @var array * @access public * @see SecurityComponent::requireLogin() */ var $requireLogin = array();/** * Login options for SecurityComponent::requireLogin() * * @var array * @access public * @see SecurityComponent::requireLogin() */ var $loginOptions = array('type' => '', 'prompt' => null);/** * An associative array of usernames/passwords used for HTTP-authenticated logins. * If using digest authentication, passwords should be MD5-hashed. * * @var array * @access public * @see SecurityComponent::requireLogin() */ var $loginUsers = array();/** * Controllers from which actions of the current controller are allowed to receive * requests. * * @var array * @access public * @see SecurityComponent::requireAuth() */ var $allowedControllers = array();/** * Actions from which actions of the current controller are allowed to receive * requests. * * @var array * @access public * @see SecurityComponent::requireAuth() */ var $allowedActions = array();/** * Form fields to disable * * @var array * @access public */ var $disabledFields = array();/** * Other components used by the Security component * * @var array * @access public */ var $components = array('RequestHandler', 'Session');/** * Holds the current action of the controller * * @var string */ var $__action = null;/** * Component startup. All security checking happens here. * * @param object $controller Instantiating controller * @access public */ function startup(&$controller) { $this->__action = strtolower($controller->action); $this->__methodsRequired($controller); $this->__secureRequired($controller); $this->__authRequired($controller); $this->__loginRequired($controller); if ((!isset($controller->params['requested']) || $controller->params['requested'] != 1) && ($this->RequestHandler->isPost() || $this->RequestHandler->isPut())) { $this->__validatePost($controller); } $this->__generateToken($controller); }/** * Sets the actions that require a POST request, or empty for all actions * * @access public */ function requirePost() { $args = func_get_args(); $this->__requireMethod('Post', $args); }/** * Sets the actions that require a GET request, or empty for all actions * * @access public */ function requireGet() { $args = func_get_args(); $this->__requireMethod('Get', $args); }/** * Sets the actions that require a PUT request, or empty for all actions * * @access public */ function requirePut() { $args = func_get_args(); $this->__requireMethod('Put', $args); }/** * Sets the actions that require a DELETE request, or empty for all actions * * @access public */ function requireDelete() { $args = func_get_args(); $this->__requireMethod('Delete', $args); }/** * Sets the actions that require a request that is SSL-secured, or empty for all actions * * @access public */ function requireSecure() { $args = func_get_args(); $this->__requireMethod('Secure', $args); }/** * Sets the actions that require an authenticated request, or empty for all actions * * @access public */ function requireAuth() { $args = func_get_args(); $this->__requireMethod('Auth', $args); }/** * Sets the actions that require an HTTP-authenticated request, or empty for all actions * * @access public */ function requireLogin() { $args = func_get_args(); $base = $this->loginOptions; foreach ($args as $i => $arg) { if (is_array($arg)) { $this->loginOptions = $arg; unset($args[$i]); } } $this->loginOptions = array_merge($base, $this->loginOptions); $this->__requireMethod('Login', $args); if (isset($this->loginOptions['users'])) { $this->loginUsers =& $this->loginOptions['users']; } }/** * Attempts to validate the login credentials for an HTTP-authenticated request * * @param string $type Either 'basic', 'digest', or null. If null/empty, will try both. * @return mixed If successful, returns an array with login name and password, otherwise null. * @access public */ function loginCredentials($type = null) { switch (strtolower($type)) { case 'basic': $login = array('username' => env('PHP_AUTH_USER'), 'password' => env('PHP_AUTH_PW')); if (!empty($login['username'])) { return $login; } break; case 'digest': default: $digest = null; if (version_compare(phpversion(), '5.1') != -1) { $digest = env('PHP_AUTH_DIGEST'); } elseif (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if (isset($headers['Authorization']) && !empty($headers['Authorization']) && substr($headers['Authorization'], 0, 7) == 'Digest ') { $digest = substr($headers['Authorization'], 7); } } else { // Server doesn't support digest-auth headers trigger_error(__('SecurityComponent::loginCredentials() - Server does not support digest authentication', true), E_USER_WARNING); } if (!empty($digest)) { return $this->parseDigestAuthData($digest); } break; } return null; }/** * Generates the text of an HTTP-authentication request header from an array of options.. * * @param array $options Set of options for header * @return string HTTP-authentication request header * @access public */ function loginRequest($options = array()) { $options = array_merge($this->loginOptions, $options); $this->__setLoginDefaults($options); $auth = 'WWW-Authenticate: ' . ucfirst($options['type']); $out = array('realm="' . $options['realm'] . '"'); if (strtolower($options['type']) == 'digest') { $out[] = 'qop="auth"'; $out[] = 'nonce="' . uniqid() . '"'; //str_replace('-', '', String::uuid()) $out[] = 'opaque="' . md5($options['realm']).'"'; } return $auth . ' ' . join(',', $out); }/** * Parses an HTTP digest authentication response, and returns an array of the data, or null on failure. * * @param string $digest Digest authentication response * @return array Digest authentication parameters * @access public */ function parseDigestAuthData($digest) { if (substr($digest, 0, 7) == 'Digest ') { $digest = substr($digest, 7); } $keys = array(); $match = array(); $req = array('nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1); preg_match_all('@(\w+)=([\'"]?)([a-zA-Z0-9=./\_-]+)\2@', $digest, $match, PREG_SET_ORDER); foreach ($match as $i) { $keys[$i[1]] = $i[3]; unset($req[$i[1]]); } if (empty($req)) { return $keys; } else { return null; } }/** * Generates a hash to be compared with an HTTP digest-authenticated response * * @param array $data HTTP digest response data, as parsed by SecurityComponent::parseDigestAuthData() * @return string Digest authentication hash * @access public * @see SecurityComponent::parseDigestAuthData() */ function generateDigestResponseHash($data) { return md5( md5($data['username'] . ':' . $this->loginOptions['realm'] . ':' . $this->loginUsers[$data['username']]) . ':' . $data['nonce'] . ':' . $data['nc'] . ':' . $data['cnonce'] . ':' . $data['qop'] . ':' . md5(env('REQUEST_METHOD') . ':' . $data['uri']) ); }/** * Black-hole an invalid request with a 404 error or custom callback. If SecurityComponent::$blackHoleCallback * is specified, it will use this callback by executing the method indicated in $error * * @param object $controller Instantiating controller * @param string $error Error method * @return mixed If specified, controller blackHoleCallback's response, or no return otherwise * @access public * @see SecurityComponent::$blackHoleCallback */ function blackHole(&$controller, $error = '') { $this->Session->del('_Token'); if ($this->blackHoleCallback == null) { $code = 404; if ($error == 'login') { $code = 401; } $controller->redirect(null, $code, true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -