452 lines
14 KiB
Plaintext
452 lines
14 KiB
Plaintext
= sfGuard plugin (for symfony 1.0) =
|
|
|
|
The `sfGuardPlugin` is a symfony plugin that provides authentication and
|
|
authorization features above the standard security feature of symfony.
|
|
|
|
It gives you the model (user, group and permission objects) and the modules
|
|
(backend and frontend) to secure your symfony application in a minute in
|
|
a configurable plugin.
|
|
|
|
== Installation ==
|
|
|
|
* Install the plugin
|
|
|
|
{{{
|
|
symfony plugin-install http://plugins.symfony-project.com/sfGuardPlugin
|
|
}}}
|
|
|
|
* Rebuild your model
|
|
|
|
{{{
|
|
symfony propel-build-model
|
|
symfony propel-build-sql
|
|
}}}
|
|
|
|
* Update you database tables by starting from scratch (it will delete all
|
|
the existing tables, then re-create them):
|
|
|
|
{{{
|
|
symfony propel-insert-sql
|
|
}}}
|
|
|
|
or you can just create the new tables by using the generated SQL
|
|
statements in `data/sql/plugins.sfGuardAuth.lib.model.schema.sql`
|
|
|
|
* Load default fixtures (optional - it creates a superadmin user)
|
|
|
|
{{{
|
|
mkdir data/fixtures/
|
|
cp plugins/sfGuardPlugin/data/fixtures/fixtures.yml.sample data/fixtures/sfGuard.yml
|
|
|
|
symfony propel-load-data frontend # replace frontend with the name of one of your application
|
|
}}}
|
|
|
|
* Enable one or more modules in your `settings.yml` (optional)
|
|
* For your backend application: sfGuardUser, sfGuardGroup, sfGuardPermission
|
|
* For your frontend application: sfGuardAuth
|
|
|
|
{{{
|
|
all:
|
|
.settings:
|
|
enabled_modules: [default, sfGuardGroup, sfGuardUser, sfGuardPermission]
|
|
}}}
|
|
|
|
* Clear you cache
|
|
|
|
{{{
|
|
symfony cc
|
|
}}}
|
|
|
|
* Optionally enable the "Remember Me" filter in `filters.yml`
|
|
|
|
{{{
|
|
security:
|
|
class: sfGuardBasicSecurityFilter
|
|
}}}
|
|
|
|
=== Secure your application ===
|
|
|
|
To secure a symfony application:
|
|
|
|
* Enable the module `sfGuardAuth` in `settings.yml`
|
|
|
|
{{{
|
|
all:
|
|
.settings:
|
|
enabled_modules: [..., sfGuardAuth]
|
|
}}}
|
|
|
|
* Change the default login and secure modules in `settings.yml`
|
|
|
|
{{{
|
|
login_module: sfGuardAuth
|
|
login_action: signin
|
|
|
|
secure_module: sfGuardAuth
|
|
secure_action: secure
|
|
}}}
|
|
|
|
* Change the parent class in `myUser.class.php`
|
|
|
|
{{{
|
|
class myUser extends sfGuardSecurityUser
|
|
{
|
|
}
|
|
}}}
|
|
|
|
* Optionally add the following routing rules to `routing.yml`
|
|
|
|
{{{
|
|
sf_guard_signin:
|
|
url: /login
|
|
param: { module: sfGuardAuth, action: signin }
|
|
|
|
sf_guard_signout:
|
|
url: /logout
|
|
param: { module: sfGuardAuth, action: signout }
|
|
|
|
sf_guard_password:
|
|
url: /request_password
|
|
param: { module: sfGuardAuth, action: password }
|
|
}}}
|
|
|
|
You can customize the `url` parameter of each route.
|
|
N.B.: You must have a `@homepage` routing rule (used when a user sign out)
|
|
|
|
These routes are automatically registered by the plugin if the module `sfGuardAuth`
|
|
is enabled unless you defined `sf_guard_plugin_routes_register` to false
|
|
in the `app.yml` configuration file:
|
|
|
|
{{{
|
|
all:
|
|
sf_guard_plugin:
|
|
routes_register: false
|
|
}}}
|
|
|
|
* Secure some modules or your entire application in `security.yml`
|
|
|
|
{{{
|
|
default:
|
|
is_secure: on
|
|
}}}
|
|
|
|
* You're done. Now, if you try to access a secure page, you will be redirected
|
|
to the login page.
|
|
If you have loaded the default fixture file, try to login with `admin` as
|
|
username and `admin` as password.
|
|
|
|
== Manage your users, permissions and groups ==
|
|
|
|
To be able to manage your users, permissions and groups, `sfGuardPlugin` comes
|
|
with 3 modules that can be integrated in your backend application.
|
|
These modules are auto-generated thanks to the symfony admin generator.
|
|
|
|
* Enable the modules in `settings.yml`
|
|
|
|
{{{
|
|
all:
|
|
.settings:
|
|
enabled_modules: [..., sfGuardGroup, sfGuardPermission, sfGuardUser]
|
|
}}}
|
|
|
|
* Access the modules with the default route:
|
|
|
|
{{{
|
|
http://www.example.com/backend.php/sfGuardUser
|
|
}}}
|
|
|
|
== Customize sfGuardAuth module templates ==
|
|
|
|
By default, `sfGuardAuth` module comes with 2 very simple templates:
|
|
|
|
* `signinSuccess.php`
|
|
* `secureSuccess.php`
|
|
|
|
If you want to customize one of these templates:
|
|
|
|
* Create a `sfGuardAuth` module in your application (don't use the
|
|
`init-module` task, just create a `sfGuardAuth` directory)
|
|
|
|
* Create a template with the name of the template you want to customize in
|
|
the `sfGuardAuth/templates` directory
|
|
|
|
* symfony now renders your template instead of the default one
|
|
|
|
== Customize `sfGuardAuth` module actions ==
|
|
|
|
If you want to customize or add methods to the sfGuardAuth:
|
|
|
|
* Create a `sfGuardAuth` module in your application
|
|
|
|
* Create an `actions.class.php` file in your `actions` directory that inherit
|
|
from `BasesfGuardAuthActions` (don't forget to include the `BasesfGuardAuthActions`
|
|
as it can't be autoloaded by symfony)
|
|
|
|
{{{
|
|
<?php
|
|
|
|
require_once(sfConfig::get('sf_plugins_dir').'/sfGuardPlugin/modules/sfGuardAuth/lib/BasesfGuardAuthActions.class.php');
|
|
|
|
class sfGuardAuthActions extends BasesfGuardAuthActions
|
|
{
|
|
public function executeNewAction()
|
|
{
|
|
return $this->renderText('This is a new sfGuardAuth action.');
|
|
}
|
|
}
|
|
}}}
|
|
|
|
== `sfGuardSecurityUser` class ==
|
|
|
|
This class inherits from the `sfBasicSecurityUser` class from symfony and is
|
|
used for the `user` object in your symfony application.
|
|
(because you changed the `myUser` base class earlier)
|
|
|
|
So, to access it, you can use the standard `$this->getUser()` in your actions
|
|
or `$sf_user` in your templates.
|
|
|
|
`sfGuardSecurityUser` adds some methods:
|
|
|
|
* `signIn()` and `signOut()` methods
|
|
* `getGuardUser()` that returns the `sfGuardUser` object
|
|
* a bunch of proxy methods to access directly the `sfGuardUser` object
|
|
|
|
For example, to get the current username:
|
|
|
|
{{{
|
|
$this->getUser()->getGuardUser()->getUsername()
|
|
|
|
// or via the proxy method
|
|
$this->getUser()->getUsername()
|
|
}}}
|
|
|
|
== Super administrator flag ==
|
|
|
|
`sfGuardPlugin` has a notion of super administrator. A user that is a super
|
|
administrator bypasses all credential checks.
|
|
|
|
The super administrator flag cannot be set on the web, you must set the flag
|
|
directly in the database or use the pake task:
|
|
|
|
{{{
|
|
symfony promote-super-admin admin
|
|
}}}
|
|
|
|
== Validators ==
|
|
|
|
`sfGuardPlugin` comes with a validator that you can use in your modules:
|
|
`sfGuardUserValidator`.
|
|
|
|
This validator is used by the `sfGuardAuth` module to validate a user and
|
|
password and automatically signin the user.
|
|
|
|
== Customize the `sfGuardUser` model ==
|
|
|
|
The `sfGuardUser` model is quite simple. There is no `email` or `first_name`
|
|
or `birthday` columns. As you cannot add methods to the class, the `sfAuthPlugin`
|
|
gives you the possibility to define a user profile class.
|
|
|
|
By default, `sfGuardUser` looks for a `sfGuardUserProfile` class.
|
|
|
|
Here is a simple example of a `sfGuardProfile` class that you can add to `schema.yml`:
|
|
|
|
{{{
|
|
sf_guard_user_profile:
|
|
_attributes: { phpName: sfGuardUserProfile }
|
|
id:
|
|
user_id: { type: integer, foreignTable: sf_guard_user, foreignReference: id, required: true, onDelete: cascade }
|
|
first_name: varchar(20)
|
|
last_name: varchar(20)
|
|
birthday: date
|
|
}}}
|
|
|
|
You can now access the user profile via the user object:
|
|
|
|
{{{
|
|
$this->getUser()->getGuardUser()->getProfile()->getFirstName()
|
|
|
|
// or via the proxy method
|
|
$this->getUser()->getProfile()->getFirstName()
|
|
}}}
|
|
|
|
The `getProfile()` method gets the associated user profile object or creates a
|
|
new one if none already exists.
|
|
|
|
When you delete a user, the associated profile is also deleted.
|
|
|
|
You can change the name of the user profile class and the foreign key name in
|
|
`app.yml`:
|
|
|
|
{{{
|
|
all:
|
|
sf_guard_plugin:
|
|
profile_class: sfGuardUserProfile
|
|
profile_field_name: user_id
|
|
}}}
|
|
|
|
== Check the user password with an external method ==
|
|
|
|
If you don't want to store the password in the database because you already
|
|
have a LDAP server, a .htaccess file or if you store your passwords in another
|
|
table, you can provide your own `checkPassword` callable (static method or
|
|
function) in `app.yml`:
|
|
|
|
{{{
|
|
all:
|
|
sf_guard_plugin:
|
|
check_password_callable: [MyLDAPClass, checkPassword]
|
|
}}}
|
|
|
|
When symfony will call the `$this->getUser()->checkPassword()` method, it will
|
|
call your method or function. Your function must takes 2 parameters, the first
|
|
one is the username and the second one is the password. It must returns true
|
|
or false. Here is a template for such a function:
|
|
|
|
{{{
|
|
function checkLDAPPassword($username, $password)
|
|
{
|
|
$user = LDAP::getUser($username);
|
|
if ($user->checkPassword($password))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}}}
|
|
|
|
== Change the algorithm used to store passwords ==
|
|
|
|
By default, passwords are stored as a `sha1()` hash. But you can change this
|
|
with any callable in `app.yml`:
|
|
|
|
{{{
|
|
all:
|
|
sf_guard_plugin:
|
|
algorithm_callable: [MyCryptoClass, MyCryptoMethod]
|
|
}}}
|
|
|
|
or
|
|
|
|
{{{
|
|
all:
|
|
sf_guard_plugin:
|
|
algorithm_callable: md5
|
|
}}}
|
|
|
|
As the algorithm is stored for each user, you can change your mind later
|
|
without the need to regenerate all passwords for the current users.
|
|
|
|
== Change the name or expiration period of the "Remember Me" cookie ==
|
|
|
|
By default, the "Remember Me" feature creates a cookie named `sfRemember`
|
|
that will last 15 days. You can change this behavior in `app.yml`:
|
|
|
|
{{{
|
|
all:
|
|
sf_guard_plugin:
|
|
remember_key_expiration_age: 2592000 # 30 days in seconds
|
|
remember_cookie_name: myAppRememberMe
|
|
}}}
|
|
|
|
|
|
== Customize `sfGuardAuth` redirect handling ==
|
|
|
|
If you want to redirect the user to his profile after a success login or
|
|
define a logout site.
|
|
|
|
You can change the redirect values in `app.yml`:
|
|
|
|
{{{
|
|
all:
|
|
sf_guard_plugin:
|
|
success_signin_url: @my_route?param=value # the plugin use the referer as default
|
|
success_signout_url: module/action # the plugin use the referer as default
|
|
}}}
|
|
|
|
== TODO ==
|
|
|
|
* finish the `promote_super_user` task
|
|
* finish the `getPassword` method
|
|
* add support for HTTP Basic authentication
|
|
|
|
== Changelog ==
|
|
|
|
=== 1.1.16 PRE ===
|
|
|
|
=== 1.1.15 ===
|
|
|
|
* fabien: optimized getAllPermissions() number of database requests (#3238)
|
|
* fabien: added the user object as a third parameter when calling the `app_sf_guard_plugin_check_password_callable` callable (#3231)
|
|
* fabien: fixed `isSuperAdmin()` method (#2719)
|
|
* fabien: fixed schema for IPv6 (#3626)
|
|
|
|
=== 1.1.14 ===
|
|
|
|
* fabien: [BREAKS BC] renamed app_sfGuardPlugin_routes_register to app_sf_guard_plugin_routes_register (#2562)
|
|
* fabien: added HTTP status code 401 when coming from a XMLHTTPRequest (#2469)
|
|
* fabien: fixed HTTP status code for secure (403) and signin (401) actions (#2545)
|
|
|
|
=== 1.1.13 ===
|
|
|
|
* fabien: fixed isAnonymous() method (#2484)
|
|
* frederic: added PluginsfGuardUser::setPasswordHash() to be able to change the password hash directly (useful when loading fixtures)
|
|
* fabien: updated documentation about creating the new tables (#2476)
|
|
* fabien: added the BasesfGuardAuthActions inclusion when extending the sfGuardAuth class (#2296)
|
|
* francois: fixed indexes on unique columns were not unique
|
|
* francois: switched to YAML schema, to allow overriding by way of sfPropelAlternativeSchemaPlugin
|
|
* francois: added `lib/model/plugin/` classes to make the model truly extensible
|
|
|
|
=== 1.1.12 ===
|
|
|
|
* fabien: fixed typo in secureSuccess template (closes #2260)
|
|
* fabien: fixed 'secure' action in sfGuardPlugin do not need to be secure (closes #2254)
|
|
* fabien: fixed typo in sfGuardUser::getProfile()
|
|
* fabien: added some check in sfGuardSecurityUser proxy methods
|
|
|
|
=== 1.1.11 ===
|
|
|
|
* fabien: fixed array_merge_recursive causes recursion warnings in sfGuardUser.php (closes #1834)
|
|
* fabien: fixed groups, permissions, and profile saving when sfUser has no primary key (closes #1709)
|
|
* fabien: added connection parameters to all methods that interacts with the database (closes #2237)
|
|
* fabien: changed signout actions, so it doesn't require to be authenticated
|
|
* fabien: added a ->isSuperAdmin() method to the User class
|
|
* fabien: fixed connection should be used when saving model (closes #2152)
|
|
* fabien: fixed typo in modules /sfGuardAuth/config/security.yml (closes #1930)
|
|
* fabien: removed warning about foreign key and profile table
|
|
* davedash: when displaying the signin form, if no referer is set for the user we default to the last page
|
|
* davedash: updated documentation regarding remember me cookie settings (closes #2148)
|
|
* davedash: default algorithm is now sha1 not \asha1\a (closes Ticket #2189)
|
|
* davedash: made the default templates i18n compatible (closes #1662)
|
|
|
|
=== 1.1.10 ===
|
|
|
|
* davedash: reordered the if/elseif structure so no loop starves
|
|
|
|
=== 1.1.9 ===
|
|
|
|
* fabien: fixed a typo in sfGuardUser reloadGroupsAndPermissions() method (closes #1758)
|
|
* fabien: fixed "Remember Me" filter documentation (closes #1705)
|
|
|
|
=== 1.1.8 ===
|
|
|
|
* gordon: add two new config params 'success_signin_url' and 'success_signin_url'
|
|
* gordon: split 'checkPassword()' to 'checkPassword()' and 'checkPasswordByGuard()' so it is callable by your own 'check_password()'
|
|
* gordon: better redirect
|
|
* gordon: 'login_module' and 'login_action' use for 'handleErrorSignin()' and after successe login
|
|
* gordon: Added extra logic to make sure remember me code is only executed if user is not authenticated.
|
|
* fabien: fixed is_super_admin has not default value (closes #1410)
|
|
* fabien: fixed sfGuardPlugin signin.yml validation configuration (closes #1440)
|
|
* fabien: fixed missing unique indexes in sf_guard_group and sf_guard_permission (closes #1454)
|
|
* fabien: fixed sfGuardAuth should clear the credentials (closes #1537)
|
|
* davedash: giving unique indexes unique names so that sfGuardPlugin works with postgres (closes ticket #1720)
|
|
* davedash: fixed the model so getting groupPermissions works (fixes #1729)
|
|
* davedash: the signin class would keep redirecting on itself if the user is logged in
|
|
|
|
=== 1.1.7 ===
|
|
|
|
* fabien: fixed deleting sfGuardUser when no profile is defined (closes #1626)
|
|
* davedash: The setPassword() function of sfGuardSecurityUser() now saves the sfGuardUser object after setting the password
|