CakePHP(tm) : Rapid Development Framework (https://cakephp.org) Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
Licensed under The MIT License For full copyright and license information, please see the LICENSE.txt Redistributions of files must retain the above copyright notice.
AuthComponent | Authentication control component class. |
<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 0.10.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Controller\Component;
use Cake\Auth\Storage\StorageInterface;
use Cake\Controller\Component;
use Cake\Controller\Controller;
use Cake\Core\App;
use Cake\Core\Exception\Exception;
use Cake\Event\Event;
use Cake\Event\EventDispatcherTrait;
use Cake\Http\Exception\ForbiddenException;
use Cake\Http\Response;
use Cake\Http\ServerRequest;
use Cake\Routing\Router;
use Cake\Utility\Hash;
/**
* Authentication control component class.
*
* Binds access control with user authentication and session management.
*
* @property \Cake\Controller\Component\RequestHandlerComponent $RequestHandler
* @property \Cake\Controller\Component\FlashComponent $Flash
* @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html
*/
class AuthComponent extends Component
{
use EventDispatcherTrait;
/**
* The query string key used for remembering the referrered page when getting
* redirected to login.
*/
const QUERY_STRING_REDIRECT = 'redirect';
/**
* Constant for 'all'
*
* @var string
*/
const ALL = 'all';
/**
* Default config
*
* - `authenticate` - An array of authentication objects to use for authenticating users.
* You can configure multiple adapters and they will be checked sequentially
* when users are identified.
*
* ```
* $this->Auth->setConfig('authenticate', [
* 'Form' => [
* 'userModel' => 'Users.Users'
* ]
* ]);
* ```
*
* Using the class name without 'Authenticate' as the key, you can pass in an
* array of config for each authentication object. Additionally you can define
* config that should be set to all authentications objects using the 'all' key:
*
* ```
* $this->Auth->setConfig('authenticate', [
* AuthComponent::ALL => [
* 'userModel' => 'Users.Users',
* 'scope' => ['Users.active' => 1]
* ],
* 'Form',
* 'Basic'
* ]);
* ```
*
* - `authorize` - An array of authorization objects to use for authorizing users.
* You can configure multiple adapters and they will be checked sequentially
* when authorization checks are done.
*
* ```
* $this->Auth->setConfig('authorize', [
* 'Crud' => [
* 'actionPath' => 'controllers/'
* ]
* ]);
* ```
*
* Using the class name without 'Authorize' as the key, you can pass in an array
* of config for each authorization object. Additionally you can define config
* that should be set to all authorization objects using the AuthComponent::ALL key:
*
* ```
* $this->Auth->setConfig('authorize', [
* AuthComponent::ALL => [
* 'actionPath' => 'controllers/'
* ],
* 'Crud',
* 'CustomAuth'
* ]);
* ```
*
* - ~~`ajaxLogin`~~ - The name of an optional view element to render when an Ajax
* request is made with an invalid or expired session.
* **This option is deprecated since 3.3.6.** Your client side code should
* instead check for 403 status code and show appropriate login form.
*
* - `flash` - Settings to use when Auth needs to do a flash message with
* FlashComponent::set(). Available keys are:
*
* - `key` - The message domain to use for flashes generated by this component,
* defaults to 'auth'.
* - `element` - Flash element to use, defaults to 'default'.
* - `params` - The array of additional params to use, defaults to ['class' => 'error']
*
* - `loginAction` - A URL (defined as a string or array) to the controller action
* that handles logins. Defaults to `/users/login`.
*
* - `loginRedirect` - Normally, if a user is redirected to the `loginAction` page,
* the location they were redirected from will be stored in the session so that
* they can be redirected back after a successful login. If this session value
* is not set, redirectUrl() method will return the URL specified in `loginRedirect`.
*
* - `logoutRedirect` - The default action to redirect to after the user is logged out.
* While AuthComponent does not handle post-logout redirection, a redirect URL
* will be returned from `AuthComponent::logout()`. Defaults to `loginAction`.
*
* - `authError` - Error to display when user attempts to access an object or
* action to which they do not have access.
*
* - `unauthorizedRedirect` - Controls handling of unauthorized access.
*
* - For default value `true` unauthorized user is redirected to the referrer URL
* or `$loginRedirect` or '/'.
* - If set to a string or array the value is used as a URL to redirect to.
* - If set to false a `ForbiddenException` exception is thrown instead of redirecting.
*
* - `storage` - Storage class to use for persisting user record. When using
* stateless authenticator you should set this to 'Memory'. Defaults to 'Session'.
*
* - `checkAuthIn` - Name of event for which initial auth checks should be done.
* Defaults to 'Controller.startup'. You can set it to 'Controller.initialize'
* if you want the check to be done before controller's beforeFilter() is run.
*
* @var array
*/
protected $_defaultConfig = [
'authenticate' => null,
'authorize' => null,
'ajaxLogin' => null,
'flash' => null,
'loginAction' => null,
'loginRedirect' => null,
'logoutRedirect' => null,
'authError' => null,
'unauthorizedRedirect' => true,
'storage' => 'Session',
'checkAuthIn' => 'Controller.startup'
];
/**
* Other components utilized by AuthComponent
*
* @var array
*/
public $components = ['RequestHandler', 'Flash'];
/**
* Objects that will be used for authentication checks.
*
* @var \Cake\Auth\BaseAuthenticate[]
*/
protected $_authenticateObjects = [];
/**
* Objects that will be used for authorization checks.
*
* @var \Cake\Auth\BaseAuthorize[]
*/
protected $_authorizeObjects = [];
/**
* Storage object.
*
* @var \Cake\Auth\Storage\StorageInterface|null
*/
protected $_storage;
/**
* Controller actions for which user validation is not required.
*
* @var array
* @see \Cake\Controller\Component\AuthComponent::allow()
*/
public $allowedActions = [];
/**
* Request object
*
* @var \Cake\Http\ServerRequest
*/
public $request;
/**
* Response object
*
* @var \Cake\Http\Response
*/
public $response;
/**
* Instance of the Session object
*
* @var \Cake\Http\Session
* @deprecated 3.1.0 Will be removed in 4.0
*/
public $session;
/**
* The instance of the Authenticate provider that was used for
* successfully logging in the current user after calling `login()`
* in the same request
*
* @var \Cake\Auth\BaseAuthenticate|null
*/
protected $_authenticationProvider;
/**
* The instance of the Authorize provider that was used to grant
* access to the current user to the URL they are requesting.
*
* @var \Cake\Auth\BaseAuthorize|null
*/
protected $_authorizationProvider;
/**
* Initialize properties.
*
* @param array $config The config data.
* @return void
*/
public function initialize(array $config)
{
$controller = $this->_registry->getController();
$this->setEventManager($controller->getEventManager());
$this->response =& $controller->response;
$this->session = $controller->getRequest()->getSession();
if ($this->getConfig('ajaxLogin')) {
deprecationWarning(
'The `ajaxLogin` option is deprecated. Your client-side ' .
'code should instead check for 403 status code and show ' .
'appropriate login form.'
);
}
}
/**
* Callback for Controller.startup event.
*
* @param \Cake\Event\Event $event Event instance.
* @return \Cake\Http\Response|null
*/
public function startup(Event $event)
{
return $this->authCheck($event);
}
/**
* Main execution method, handles initial authentication check and redirection
* of invalid users.
*
* The auth check is done when event name is same as the one configured in
* `checkAuthIn` config.
*
* @param \Cake\Event\Event $event Event instance.
* @return \Cake\Http\Response|null
* @throws \ReflectionException
*/
public function authCheck(Event $event)
{
if ($this->_config['checkAuthIn'] !== $event->getName()) {
return null;
}
/** @var \Cake\Controller\Controller $controller */
$controller = $event->getSubject();
$action = strtolower($controller->getRequest()->getParam('action'));
if (!$controller->isAction($action)) {
return null;
}
$this->_setDefaults();
if ($this->_isAllowed($controller)) {
return null;
}
$isLoginAction = $this->_isLoginAction($controller);
if (!$this->_getUser()) {
if ($isLoginAction) {
return null;
}
$result = $this->_unauthenticated($controller);
if ($result instanceof Response) {
$event->stopPropagation();
}
return $result;
}
if ($isLoginAction ||
empty($this->_config['authorize']) ||
$this->isAuthorized($this->user())
) {
return null;
}
$event->stopPropagation();
return $this->_unauthorized($controller);
}
/**
* Events supported by this component.
*
* @return array
*/
public function implementedEvents()
{
return [
'Controller.initialize' => 'authCheck',
'Controller.startup' => 'startup',
];
}
/**
* Checks whether current action is accessible without authentication.
*
* @param \Cake\Controller\Controller $controller A reference to the instantiating
* controller object
* @return bool True if action is accessible without authentication else false
*/
protected function _isAllowed(Controller $controller)
{
$action = strtolower($controller->getRequest()->getParam('action'));
return in_array($action, array_map('strtolower', $this->allowedActions));
}
/**
* Handles unauthenticated access attempt. First the `unauthenticated()` method
* of the last authenticator in the chain will be called. The authenticator can
* handle sending response or redirection as appropriate and return `true` to
* indicate no further action is necessary. If authenticator returns null this
* method redirects user to login action. If it's an AJAX request and config
* `ajaxLogin` is specified that element is rendered else a 403 HTTP status code
* is returned.
*
* @param \Cake\Controller\Controller $controller A reference to the controller object.
* @return \Cake\Http\Response|null Null if current action is login action
* else response object returned by authenticate object or Controller::redirect().
* @throws \Cake\Core\Exception\Exception
*/
protected function _unauthenticated(Controller $controller)
{
if (empty($this->_authenticateObjects)) {
$this->constructAuthenticate();
}
$response = $this->response;
$auth = end($this->_authenticateObjects);
if ($auth === false) {
throw new Exception('At least one authenticate object must be available.');
}
$result = $auth->unauthenticated($controller->getRequest(), $response);
if ($result !== null) {
return $result;
}
if (!$controller->getRequest()->is('ajax')) {
$this->flash($this->_config['authError']);
return $controller->redirect($this->_loginActionRedirectUrl());
}
if (!empty($this->_config['ajaxLogin'])) {
$controller->viewBuilder()->setTemplatePath('Element');
$response = $controller->render(
$this->_config['ajaxLogin'],
$this->RequestHandler->ajaxLayout
);
}
return $response->withStatus(403);
}
/**
* Returns the URL of the login action to redirect to.
*
* This includes the redirect query string if applicable.
*
* @return array|string
*/
protected function _loginActionRedirectUrl()
{
$urlToRedirectBackTo = $this->_getUrlToRedirectBackTo();
$loginAction = $this->_config['loginAction'];
if ($urlToRedirectBackTo === '/') {
return $loginAction;
}
if (is_array($loginAction)) {
$loginAction['?'][static::QUERY_STRING_REDIRECT] = $urlToRedirectBackTo;
} else {
$char = strpos($loginAction, '?') === false ? '?' : '&';
$loginAction .= $char . static::QUERY_STRING_REDIRECT . '=' . urlencode($urlToRedirectBackTo);
}
return $loginAction;
}
/**
* Normalizes config `loginAction` and checks if current request URL is same as login action.
*
* @param \Cake\Controller\Controller $controller A reference to the controller object.
* @return bool True if current action is login action else false.
*/
protected function _isLoginAction(Controller $controller)
{
$uri = $controller->request->getUri();
$url = Router::normalize($uri->getPath());
$loginAction = Router::normalize($this->_config['loginAction']);
return $loginAction === $url;
}
/**
* Handle unauthorized access attempt
*
* @param \Cake\Controller\Controller $controller A reference to the controller object
* @return \Cake\Http\Response
* @throws \Cake\Http\Exception\ForbiddenException
*/
protected function _unauthorized(Controller $controller)
{
if ($this->_config['unauthorizedRedirect'] === false) {
throw new ForbiddenException($this->_config['authError']);
}
$this->flash($this->_config['authError']);
if ($this->_config['unauthorizedRedirect'] === true) {
$default = '/';
if (!empty($this->_config['loginRedirect'])) {
$default = $this->_config['loginRedirect'];
}
if (is_array($default)) {
$default['_base'] = false;
}
$url = $controller->referer($default, true);
} else {
$url = $this->_config['unauthorizedRedirect'];
}
return $controller->redirect($url);
}
/**
* Sets defaults for configs.
*
* @return void
*/
protected function _setDefaults()
{
$defaults = [
'authenticate' => ['Form'],
'flash' => [
'element' => 'error',
'key' => 'flash',
'params' => ['class' => 'error']
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
'plugin' => null
],
'logoutRedirect' => $this->_config['loginAction'],
'authError' => __d('cake', 'You are not authorized to access that location.')
];
$config = $this->getConfig();
foreach ($config as $key => $value) {
if ($value !== null) {
unset($defaults[$key]);
}
}
$this->setConfig($defaults);
}
/**
* Check if the provided user is authorized for the request.
*
* Uses the configured Authorization adapters to check whether or not a user is authorized.
* Each adapter will be checked in sequence, if any of them return true, then the user will
* be authorized for the request.
*
* @param array|\ArrayAccess|null $user The user to check the authorization of.
* If empty the user fetched from storage will be used.
* @param \Cake\Http\ServerRequest|null $request The request to authenticate for.
* If empty, the current request will be used.
* @return bool True if $user is authorized, otherwise false
*/
public function isAuthorized($user = null, ServerRequest $request = null)
{
if (empty($user) && !$this->user()) {
return false;
}
if (empty($user)) {
$user = $this->user();
}
if (empty($request)) {
$request = $this->getController()->getRequest();
}
if (empty($this->_authorizeObjects)) {
$this->constructAuthorize();
}
foreach ($this->_authorizeObjects as $authorizer) {
if ($authorizer->authorize($user, $request) === true) {
$this->_authorizationProvider = $authorizer;
return true;
}
}
return false;
}
/**
* Loads the authorization objects configured.
*
* @return array|null The loaded authorization objects, or null when authorize is empty.
* @throws \Cake\Core\Exception\Exception
*/
public function constructAuthorize()
{
if (empty($this->_config['authorize'])) {
return null;
}
$this->_authorizeObjects = [];
$authorize = Hash::normalize((array)$this->_config['authorize']);
$global = [];
if (isset($authorize[AuthComponent::ALL])) {
$global = $authorize[AuthComponent::ALL];
unset($authorize[AuthComponent::ALL]);
}
foreach ($authorize as $alias => $config) {
if (!empty($config['className'])) {
$class = $config['className'];
unset($config['className']);
} else {
$class = $alias;
}
$className = App::className($class, 'Auth', 'Authorize');
if (!class_exists($className)) {
throw new Exception(sprintf('Authorization adapter "%s" was not found.', $class));
}
if (!method_exists($className, 'authorize')) {
throw new Exception('Authorization objects must implement an authorize() method.');
}
$config = (array)$config + $global;
$this->_authorizeObjects[$alias] = new $className($this->_registry, $config);
}
return $this->_authorizeObjects;
}
/**
* Getter for authorize objects. Will return a particular authorize object.
*
* @param string $alias Alias for the authorize object
* @return \Cake\Auth\BaseAuthorize|null
*/
public function getAuthorize($alias)
{
if (empty($this->_authorizeObjects)) {
$this->constructAuthorize();
}
return isset($this->_authorizeObjects[$alias]) ? $this->_authorizeObjects[$alias] : null;
}
/**
* Takes a list of actions in the current controller for which authentication is not required, or
* no parameters to allow all actions.
*
* You can use allow with either an array or a simple string.
*
* ```
* $this->Auth->allow('view');
* $this->Auth->allow(['edit', 'add']);
* ```
* or to allow all actions
* ```
* $this->Auth->allow();
* ```
*
* @param string|array|null $actions Controller action name or array of actions
* @return void
* @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#making-actions-public
*/
public function allow($actions = null)
{
if ($actions === null) {
$controller = $this->_registry->getController();
$this->allowedActions = get_class_methods($controller);
return;
}
$this->allowedActions = array_merge($this->allowedActions, (array)$actions);
}
/**
* Removes items from the list of allowed/no authentication required actions.
*
* You can use deny with either an array or a simple string.
*
* ```
* $this->Auth->deny('view');
* $this->Auth->deny(['edit', 'add']);
* ```
* or
* ```
* $this->Auth->deny();
* ```
* to remove all items from the allowed list
*
* @param string|array|null $actions Controller action name or array of actions
* @return void
* @see \Cake\Controller\Component\AuthComponent::allow()
* @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#making-actions-require-authorization
*/
public function deny($actions = null)
{
if ($actions === null) {
$this->allowedActions = [];
return;
}
foreach ((array)$actions as $action) {
$i = array_search($action, $this->allowedActions);
if (is_int($i)) {
unset($this->allowedActions[$i]);
}
}
$this->allowedActions = array_values($this->allowedActions);
}
/**
* Set provided user info to storage as logged in user.
*
* The storage class is configured using `storage` config key or passing
* instance to AuthComponent::storage().
*
* @param array|\ArrayAccess $user User data.
* @return void
* @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#identifying-users-and-logging-them-in
*/
public function setUser($user)
{
$this->storage()->write($user);
}
/**
* Log a user out.
*
* Returns the logout action to redirect to. Triggers the `Auth.logout` event
* which the authenticate classes can listen for and perform custom logout logic.
*
* @return string Normalized config `logoutRedirect`
* @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#logging-users-out
*/
public function logout()
{
$this->_setDefaults();
if (empty($this->_authenticateObjects)) {
$this->constructAuthenticate();
}
$user = (array)$this->user();
$this->dispatchEvent('Auth.logout', [$user]);
$this->storage()->delete();
return Router::normalize($this->_config['logoutRedirect']);
}
/**
* Get the current user from storage.
*
* @param string|null $key Field to retrieve. Leave null to get entire User record.
* @return mixed|null Either User record or null if no user is logged in, or retrieved field if key is specified.
* @link https://book.cakephp.org/3.0/en/controllers/components/authentication.html#accessing-the-logged-in-user
*/
public function user($key = null)
{
$user = $this->storage()->read();
if (!$user) {
return null;
}
if ($key === null) {
return $user;
}
return Hash::get($user, $key);
}
/**
* Similar to AuthComponent::user() except if user is not found in
* configured storage, connected authentication objects will have their
* getUser() methods called.
*
* This lets stateless authentication methods function correctly.
*
* @return bool true If a user can be found, false if one cannot.
*/
protected function _getUser()
{
$user = $this->user();
if ($user) {
return true;
}
if (empty($this->_authenticateObjects)) {
$this->constructAuthenticate();
}
foreach ($this->_authenticateObjects as $auth) {
$result = $auth->getUser($this->getController()->getRequest());
if (!empty($result) && is_array($result)) {
$this->_authenticationProvider = $auth;
$event = $this->dispatchEvent('Auth.afterIdentify', [$result, $auth]);
if ($event->getResult() !== null) {
$result = $event->getResult();
}
$this->storage()->write($result);
return true;
}
}
return false;
}
/**
* Get the URL a user should be redirected to upon login.
*
* Pass a URL in to set the destination a user should be redirected to upon
* logging in.
*
* If no parameter is passed, gets the authentication redirect URL. The URL
* returned is as per following rules:
*
* - Returns the normalized redirect URL from storage if it is
* present and for the same domain the current app is running on.
* - If there is no URL returned from storage and there is a config
* `loginRedirect`, the `loginRedirect` value is returned.
* - If there is no session and no `loginRedirect`, / is returned.
*
* @param string|array|null $url Optional URL to write as the login redirect URL.
* @return string Redirect URL
*/
public function redirectUrl($url = null)
{
$redirectUrl = $this->getController()->getRequest()->getQuery(static::QUERY_STRING_REDIRECT);
if ($redirectUrl && (substr($redirectUrl, 0, 1) !== '/' || substr($redirectUrl, 0, 2) === '//')) {
$redirectUrl = null;
}
if ($url !== null) {
$redirectUrl = $url;
} elseif ($redirectUrl) {
if (Router::normalize($redirectUrl) === Router::normalize($this->_config['loginAction'])) {
$redirectUrl = $this->_config['loginRedirect'];
}
} elseif ($this->_config['loginRedirect']) {
$redirectUrl = $this->_config['loginRedirect'];
} else {
$redirectUrl = '/';
}
if (is_array($redirectUrl)) {
return Router::url($redirectUrl + ['_base' => false]);
}
return $redirectUrl;
}
/**
* Use the configured authentication adapters, and attempt to identify the user
* by credentials contained in $request.
*
* Triggers `Auth.afterIdentify` event which the authenticate classes can listen
* to.
*
* @return array|bool User record data, or false, if the user could not be identified.
*/
public function identify()
{
$this->_setDefaults();
if (empty($this->_authenticateObjects)) {
$this->constructAuthenticate();
}
foreach ($this->_authenticateObjects as $auth) {
$result = $auth->authenticate($this->getController()->getRequest(), $this->response);
if (!empty($result)) {
$this->_authenticationProvider = $auth;
$event = $this->dispatchEvent('Auth.afterIdentify', [$result, $auth]);
if ($event->getResult() !== null) {
return $event->getResult();
}
return $result;
}
}
return false;
}
/**
* Loads the configured authentication objects.
*
* @return array|null The loaded authorization objects, or null on empty authenticate value.
* @throws \Cake\Core\Exception\Exception
*/
public function constructAuthenticate()
{
if (empty($this->_config['authenticate'])) {
return null;
}
$this->_authenticateObjects = [];
$authenticate = Hash::normalize((array)$this->_config['authenticate']);
$global = [];
if (isset($authenticate[AuthComponent::ALL])) {
$global = $authenticate[AuthComponent::ALL];
unset($authenticate[AuthComponent::ALL]);
}
foreach ($authenticate as $alias => $config) {
if (!empty($config['className'])) {
$class = $config['className'];
unset($config['className']);
} else {
$class = $alias;
}
$className = App::className($class, 'Auth', 'Authenticate');
if (!class_exists($className)) {
throw new Exception(sprintf('Authentication adapter "%s" was not found.', $class));
}
if (!method_exists($className, 'authenticate')) {
throw new Exception('Authentication objects must implement an authenticate() method.');
}
$config = array_merge($global, (array)$config);
$this->_authenticateObjects[$alias] = new $className($this->_registry, $config);
$this->getEventManager()->on($this->_authenticateObjects[$alias]);
}
return $this->_authenticateObjects;
}
/**
* Get/set user record storage object.
*
* @param \Cake\Auth\Storage\StorageInterface|null $storage Sets provided
* object as storage or if null returns configured storage object.
* @return \Cake\Auth\Storage\StorageInterface|null
*/
public function storage(StorageInterface $storage = null)
{
if ($storage !== null) {
$this->_storage = $storage;
return null;
}
if ($this->_storage) {
return $this->_storage;
}
$config = $this->_config['storage'];
if (is_string($config)) {
$class = $config;
$config = [];
} else {
$class = $config['className'];
unset($config['className']);
}
$className = App::className($class, 'Auth/Storage', 'Storage');
if (!class_exists($className)) {
throw new Exception(sprintf('Auth storage adapter "%s" was not found.', $class));
}
$request = $this->getController()->getRequest();
$response = $this->getController()->getResponse();
$this->_storage = new $className($request, $response, $config);
return $this->_storage;
}
/**
* Magic accessor for backward compatibility for property `$sessionKey`.
*
* @param string $name Property name
* @return mixed
*/
public function __get($name)
{
if ($name === 'sessionKey') {
return $this->storage()->getConfig('key');
}
return parent::__get($name);
}
/**
* Magic setter for backward compatibility for property `$sessionKey`.
*
* @param string $name Property name.
* @param mixed $value Value to set.
* @return void
*/
public function __set($name, $value)
{
if ($name === 'sessionKey') {
$this->_storage = null;
if ($value === false) {
$this->setConfig('storage', 'Memory');
return;
}
$this->setConfig('storage', 'Session');
$this->storage()->setConfig('key', $value);
return;
}
$this->{$name} = $value;
}
/**
* Getter for authenticate objects. Will return a particular authenticate object.
*
* @param string $alias Alias for the authenticate object
*
* @return \Cake\Auth\BaseAuthenticate|null
*/
public function getAuthenticate($alias)
{
if (empty($this->_authenticateObjects)) {
$this->constructAuthenticate();
}
return isset($this->_authenticateObjects[$alias]) ? $this->_authenticateObjects[$alias] : null;
}
/**
* Set a flash message. Uses the Flash component with values from `flash` config.
*
* @param string $message The message to set.
* @return void
*/
public function flash($message)
{
if ($message === false) {
return;
}
$this->Flash->set($message, $this->_config['flash']);
}
/**
* If login was called during this request and the user was successfully
* authenticated, this function will return the instance of the authentication
* object that was used for logging the user in.
*
* @return \Cake\Auth\BaseAuthenticate|null
*/
public function authenticationProvider()
{
return $this->_authenticationProvider;
}
/**
* If there was any authorization processing for the current request, this function
* will return the instance of the Authorization object that granted access to the
* user to the current address.
*
* @return \Cake\Auth\BaseAuthorize|null
*/
public function authorizationProvider()
{
return $this->_authorizationProvider;
}
/**
* Returns the URL to redirect back to or / if not possible.
*
* This method takes the referrer into account if the
* request is not of type GET.
*
* @return string
*/
protected function _getUrlToRedirectBackTo()
{
$urlToRedirectBackTo = $this->request->getRequestTarget();
if (!$this->request->is('get')) {
$urlToRedirectBackTo = $this->request->referer(true);
}
return $urlToRedirectBackTo;
}
}