The Security Component creates an easy way to integrate tighter security in your application. An interface for managing HTTP-authenticated requests can be created with Security Component. It is configured in the beforeFilter() of your controllers. It has several configurable parameters. All of these properties can be set directly or through setter methods of the same name.
If an action is restricted using the Security Component it is black-holed as an invalid request which will result in a 404 error by default. You can configure this behavior by setting the $this->Security->blackHoleCallback property to a callback function in the controller. Keep in mind that black holes from all of the Security Component’s methods will be run through this callback method.
By using the Security Component you automatically get
CSRF and
form tampering protection. Hidden token fields will automatically be
inserted into forms and checked by the Security component. Among other
things, a form submission will not be accepted after a certain period of
inactivity, which depends on the setting of Security.level
. On
‘high’, this timeout is as short as 10 minutes. Other token fields
include a randomly generated nonce (one-time id) and a hash of fields
which (and only which) must be present in the submitted POST data.
If you are using Security component’s form protection features and other
components that process form data in their startup()
callbacks, be
sure to place Security Component before those components in your
$components
array.
When using the Security Component you must use the FormHelper to
create your forms. The Security Component looks for certain indicators
that are created and managed by the FormHelper (especially those created
in create() and end()). Dynamically altering the fields that are
submitted in a POST request (e.g. disabling, deleting or creating new
fields via JavaScript) is likely to trigger a black-holing of the
request. See the $validatePost
or $disabledFields
configuration
parameters.
Model.fieldname
).false
to completely skip the validation of POST requests,
essentially turning CSRF protection off.Sets the actions that require a POST request. Takes any number of arguments. Can be called with no arguments to force all actions to require a POST.
Sets the actions that require a SSL-secured request. Takes any number of arguments. Can be called with no arguments to force all actions to require a SSL-secured.
Sets the actions that require a valid Security Component generated token. Takes any number of arguments. Can be called with no arguments to force all actions to require a valid authentication.
Sets the actions that require a valid HTTP-Authenticated request. Takes any number of arguments. Can be called with no arguments to force all actions to require valid HTTP-authentication.
Attempt to validate login credentials for a HTTP-authenticated request. $type is the type of HTTP-Authentication you want to check. Either ‘basic’, or ‘digest’. If left null/empty both will be tried. Returns an array with login name and password if successful.
Generates the text for an HTTP-Authenticate request header from an array of $options.
$options generally contains a ‘type’, ‘realm’ . Type indicate which HTTP-Authenticate method to use. Realm defaults to the current HTTP server environment.
Parse an HTTP digest authentication request. Returns and array of digest data as an associative array if succesful, and null on failure.
Creates a hash that to be compared with an HTTP digest-authenticated response. $data should be an array created by SecurityComponent::parseDigestAuthData().
Black-hole an invalid request with a 404 error or a custom callback. With no callback, the request will be exited. If a controller callback is set to SecurityComponent::blackHoleCallback, it will be called and passed any error information.
Using the security component is generally done in the controller beforeFilter(). You would specify the security restrictions you want and the Security Component will enforce them on its startup.
<?php
class WidgetController extends AppController {
var $components = array('Security');
function beforeFilter() {
$this->Security->requirePost('delete');
}
}
?>
In this example the delete action can only be successfully triggered if it recieves a POST request.
<?php
class WidgetController extends AppController {
var $components = array('Security');
function beforeFilter() {
if(isset($this->params[Configure::read('Routing.admin')])){
$this->Security->requireSecure();
}
}
}
?>
This example would force all actions that had admin routing to require secure SSL requests.
[Note Routing.admin is deprecated in 1.3. Use Routing.prefixes instead]
<?php
class WidgetController extends AppController {
var $components = array('Security');
function beforeFilter() {
if(isset($this->params[Configure::read('Routing.admin')])){
$this->Security->blackHoleCallback = 'forceSSL';
$this->Security->requireSecure();
}
}
function forceSSL() {
$this->redirect('https://' . env('SERVER_NAME') . $this->here);
}
}
?>
This example would force all actions that had admin routing to require secure SSL requests. When the request is black holed, it will call the nominated forceSSL() callback which will redirect non-secure requests to secure requests automatically.
The SecurityComponent has some very powerful authentication features. Sometimes you may need to protect some functionality inside your application using HTTP Basic Authentication. One common usage for HTTP Auth is protecting a REST or SOAP API.
This type of authentication is called basic for a reason. Unless you’re transferring information over SSL, credentials will be transferred in plain text.
Using the SecurityComponent for HTTP authentication is easy. The code example below includes the SecurityComponent and adds a few lines of code inside the controller’s beforeFilter method.
class ApiController extends AppController {
var $name = 'Api';
var $uses = array();
var $components = array('Security');
function beforeFilter() {
$this->Security->loginOptions = array(
'type'=>'basic',
'realm'=>'MyRealm'
);
$this->Security->loginUsers = array(
'john'=>'johnspassword',
'jane'=>'janespassword'
);
$this->Security->requireLogin();
}
function index() {
//protected application logic goes here...
}
}
The loginOptions property of the SecurityComponent is an associative array specifying how logins should be handled. You only need to specify the type as basic to get going. Specify the realm if you want display a nice message to anyone trying to login or if you have several authenticated sections (= realms) of your application you want to keep separate.
The loginUsers property of the SecurityComponent is an associative array containing users and passwords that should have access to this realm. The examples here use hard-coded user information, but you’ll probably want to use a model to make your authentication credentials more manageable.
Finally, requireLogin() tells SecurityComponent that this Controller requires login. As with requirePost(), above, providing method names will protect those methods while keeping others open.