Also available in these languages:
DeutschEnglishEspañolFrançaisBahasa Indonesia日本語polskiPortuguêsRomâniaРусскийsvenska简体中文

Authentication and Authorization

Authentication and authorization are required for a Web page that should be limited to certain users. Authentication is about verifying whether someone is who he claims he is. It usually involves a username and a password, but may include any other methods of demonstrating identity, such as a smart card, fingerprints, etc. Authorization is finding out if the person, once identified (authenticated), is permitted to manipulate specific resources. This is usually determined by finding out if that person is of a particular role that has access to the resources.

Yii has a built-in authentication/authorization (auth) framework which is easy to use and can be customized for special needs.

The central piece in the Yii auth framework is a pre-declared user application component which is an object implementing the IWebUser interface. The user component represents the persistent identity information for the current user. We can access it at any place using Yii::app()->user.

Using the user component, we can check if a user is logged in or not via CWebUser::isGuest; we can login and logout a user; we can check if the user can perform specific operations by calling CWebUser::checkAccess; and we can also obtain the unique identifier and other persistent identity information about the user.

Defining Identity Class

In order to authenticate a user, we define an identity class which contains the actual authentication logic. The identity class should implement the IUserIdentity interface. Different classes may be implemented for different authentication approaches (e.g. OpenID, LDAP). A good start is by extending CUserIdentity which is a base class for the authentication approach based on username and password.

The main work in defining an identity class is the implementation of the IUserIdentity::authenticate method. An identity class may also declare additional identity information that needs to be persistent during the user session.

In the following example, we validate the given username and password against the user table in a database using Active Record. We also override the getId method to return the _id variable which is set during authentication (the default implementation would return the username as the ID). During authentication, we store the retrieved title information in a state with the same name by calling CBaseUserIdentity::setState.

class UserIdentity extends CUserIdentity
{
    private $_id;
    public function authenticate()
    {
        $record=User::model()->findByAttributes(array('username'=>$this->username));
        if($record===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if($record->password!==md5($this->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->_id=$record->id;
            $this->setState('title', $record->title);
            $this->errorCode=self::ERROR_NONE;
        }
        return !$this->errorCode;
    }
 
    public function getId()
    {
        return $this->_id;
    }
}

Information stored in a state (by calling CBaseUserIdentity::setState) will be passed to CWebUser which stores them in a persistent storage, such as session. These information can be accessed like properties of CWebUser. For example, we can obtain the title information of the current user by Yii::app()->user->title (This has been available since version 1.0.3. In prior versions, we should use Yii::app()->user->getState('title'), instead.)

Info: By default, CWebUser uses session as persistent storage for user identity information. If cookie-based login is enabled (by setting CWebUser::allowAutoLogin to be true), the user identity information may also be saved in cookie. Make sure you do not declare sensitive information (e.g. password) to be persistent.

Login and Logout

Using the identity class and the user component, we can implement login and logout actions easily.

// Login a user with the provided username and password.
$identity=new UserIdentity($username,$password);
if($identity->authenticate())
    Yii::app()->user->login($identity);
else
    echo $identity->errorMessage;
......
// Logout the current user
Yii::app()->user->logout();

By default, a user will be logged out after a certain period of inactivity, depending on the session configuration. To change this behavior, we can set the allowAutoLogin property of the user component to be true and pass a duration parameter to the CWebUser::login method. The user will then remain logged in for the specified duration, even if he closes his browser window. Note that this feature requires the user's browser to accept cookies.

// Keep the user logged in for 7 days.
// Make sure allowAutoLogin is set true for the user component.
Yii::app()->user->login($identity,3600*24*7);

Access Control Filter

Access control filter is a preliminary authorization scheme that checks if the current user can perform the requested controller action. The authorization is based on user's name, client IP address and request types. It is provided as a filter named as "accessControl".

Tip: Access control filter is sufficient for simple scenarios. For complex access control, you may use role-based access (RBAC) which is to be covered shortly.

To control the access to actions in a controller, we install the access control filter by overriding CController::filters (see Filter for more details about installing filters).

class PostController extends CController
{
    ......
    public function filters()
    {
        return array(
            'accessControl',
        );
    }
}

In the above, we specify that the access control filter should be applied to every action of PostController. The detailed authorization rules used by the filter are specified by overriding CController::accessRules in the controller class.

class PostController extends CController
{
    ......
    public function accessRules()
    {
        return array(
            array('deny',
                'actions'=>array('create', 'edit'),
                'users'=>array('?'),
            ),
            array('allow',
                'actions'=>array('delete'),
                'roles'=>array('admin'),
            ),
            array('deny',
                'actions'=>array('delete'),
                'users'=>array('*'),
            ),
        );
    }
}

The above code specifies three rules, each represented as an array. The first element of the array is either 'allow' or 'deny' and the rest name-value pairs specify the pattern parameters of the rule. These rules read: the create and edit actions cannot be executed by anonymous users; the delete action can be executed by users with admin role; and the delete action cannot be executed by anyone.

The access rules are evaluated one by one in the order they are specified. The first rule that matches the current pattern (e.g. username, roles, client IP, address) determines the authorization result. If this rule is an allow rule, the action can be executed; if it is a deny rule, the action cannot be executed; if none of the rules matches the context, the action can still be executed.

Tip: To ensure an action does not get executed under certain contexts, it is beneficial to always specify a matching-all deny rule at the end of rule set, like the following:

return array(
    // ... other rules...
    // the following rule denies 'delete' action for all contexts
    array('deny',
        'actions'=>array('delete'),
    ),
);

The reason for this rule is because if none of the rules matches a context, an action will be executed.

An access rule can match the following context parameters:

  • actions: specifies which actions this rule matches. This should be an array of action IDs. The comparison is case-insensitive.

  • controllers: specifies which controllers this rule matches. This should be an array of controller IDs. The comparison is case-insensitive. This option has been available since version 1.0.4.

  • users: specifies which users this rule matches. The current user's name is used for matching. The comparison is case-insensitive. Three special characters can be used here:

    • *: any user, including both anonymous and authenticated users.
    • ?: anonymous users.
    • @: authenticated users.
  • roles: specifies which roles that this rule matches. This makes use of the role-based access control feature to be described in the next subsection. In particular, the rule is applied if CWebUser::checkAccess returns true for one of the roles. Note, you should mainly use roles in an allow rule because by definition, a role represents a permission to do something. Also note, although we use the term roles here, its value can actually be any auth item, including roles, tasks and operations.

  • ips: specifies which client IP addresses this rule matches.

  • verbs: specifies which request types (e.g. GET, POST) this rule matches. The comparison is case-insensitive.

  • expression: specifies a PHP expression whose value indicates whether this rule matches. In the expression, you can use variable $user which refers to Yii::app()->user. This option has been available since version 1.0.3.

Handling Authorization Result

When authorization fails, i.e., the user is not allowed to perform the specified action, one of the following two scenarios may happen:

  • If the user is not logged in and if the loginUrl property of the user component is configured to be the URL of the login page, the browser will be redirected to that page. Note that by default, loginUrl points to the site/login page.

  • Otherwise an HTTP exception will be displayed with error code 403.

When configuring the loginUrl property, one can provide a relative or absolute URL. One can also provide an array which will be used to generate a URL by calling CWebApplication::createUrl. The first array element should specify the route to the login controller action, and the rest name-value pairs are GET parameters. For example,

array(
    ......
    'components'=>array(
        'user'=>array(
            // this is actually the default value
            'loginUrl'=>array('site/login'),
        ),
    ),
)

If the browser is redirected to the login page and the login is successful, we may want to redirect the browser back to the page that caused the authorization failure. How do we know the URL for that page? We can get this information from the returnUrl property of the user component. We can thus do the following to perform the redirection:

Yii::app()->request->redirect(Yii::app()->user->returnUrl);

Role-Based Access Control

Role-Based Access Control (RBAC) provides a simple yet powerful centralized access control. Please refer to the Wiki article for more details about comparing RBAC with other more traditional access control schemes.

Yii implements a hierarchical RBAC scheme via its authManager application component. In the following ,we first introduce the main concepts used in this scheme; we then describe how to define authorization data; at the end we show how to make use of the authorization data to perform access checking.

Overview

A fundamental concept in Yii's RBAC is authorization item. An authorization item is a permission to do something (e.g. creating new blog posts, managing users). According to its granularity and targeted audience, authorization items can be classified as operations, tasks and roles. A role consists of tasks, a task consists of operations, and an operation is a permission that is atomic. For example, we can have a system with administrator role which consists of post management task and user management task. The user management task may consist of create user, update user and delete user operations. For more flexibility, Yii also allows a role to consist of other roles or operations, a task to consist of other tasks, and an operation to consist of other operations.

An authorization item is uniquely identified by its name.

An authorization item may be associated with a business rule. A business rule is a piece of PHP code that will be executed when performing access checking with respect to the item. Only when the execution returns true, will the user be considered to have the permission represented by the item. For example, when defining an operation updatePost, we would like to add a business rule that checks if the user ID is the same as the post's author ID so that only the author himself can have the permission to update a post.

Using authorization items, we can build up an authorization hierarchy. An item A is a parent of another item B in the hierarchy if A consists of B (or say A inherits the permission(s) represented by B). An item can have multiple child items, and it can also have multipe parent items. Therefore, an authorization hierarchy is a partial-order graph rather than a tree. In this hierarchy, role items sit on top levels, operation items on bottom levels, while task items in between.

Once we have an authorization hierarchy, we can assign roles in this hierarchy to application users. A user, once assigned with a role, will have the permissions represented by the role. For example, if we assign the administrator role to a user, he will have the administrator permissions which include post management and user management (and the corresponding operations such as create user).

Now the fun part starts. In a controller action, we want to check if the current user can delete the specified post. Using the RBAC hierarchy and assignment, this can be done easily as follows:

if(Yii::app()->user->checkAccess('deletePost'))
{
    // delete the post
}

Configuring Authorization Manager

Before we set off to define an authorization hierarchy and perform access checking, we need to configure the authManager application component. Yii provides two types of authorization managers: CPhpAuthManager and CDbAuthManager. The former uses a PHP script file to store authorization data, while the latter stores authorization data in database. When we configure the authManager application component, we need to specify which component class to use and what are the initial property values for the component. For example,

return array(
    'components'=>array(
        'db'=>array(
            'class'=>'CDbConnection',
            'connectionString'=>'sqlite:path/to/file.db',
        ),
        'authManager'=>array(
            'class'=>'CDbAuthManager',
            'connectionID'=>'db',
        ),
    ),
);

We can then access the authManager application component using Yii::app()->authManager.

Defining Authorization Hierarchy

Defining authorization hierarchy involves three steps: defining authorization items, establishing relationships between authorization items, and assigning roles to application users. The authManager application component provides a whole set of APIs to accomplish these tasks.

To define an authorization item, call one of the following methods, depending on the type of the item:

Once we have a set of authorization items, we can call the following methods to establish relationships between authorization items:

And finally, we call the following methods to assign role items to individual users:

Below we show an example about building an authorization hierarchy with the provided APIs:

$auth=Yii::app()->authManager;
 
$auth->createOperation('createPost','create a post');
$auth->createOperation('readPost','read a post');
$auth->createOperation('updatePost','update a post');
$auth->createOperation('deletePost','delete a post');
 
$bizRule='return Yii::app()->user->id==$params["post"]->authID;';
$task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule);
$task->addChild('updatePost');
 
$role=$auth->createRole('reader');
$role->addChild('readPost');
 
$role=$auth->createRole('author');
$role->addChild('reader');
$role->addChild('createPost');
$role->addChild('updateOwnPost');
 
$role=$auth->createRole('editor');
$role->addChild('reader');
$role->addChild('updatePost');
 
$role=$auth->createRole('admin');
$role->addChild('editor');
$role->addChild('author');
$role->addChild('deletePost');
 
$auth->assign('reader','readerA');
$auth->assign('author','authorB');
$auth->assign('editor','editorC');
$auth->assign('admin','adminD');

Info: While the above example looks long and tedious, it is mainly for demonstrative purpose. Developers usually need to develop some user interfaces so that end users can use to establish an authorization hierarchy more intuitively.

Using Business Rules

When we are defining the authorization hierarchy, we can associate a role, a task or an operation with a so-called business rule. We may also associate a business rule when we assign a role to a user. A business rule is a piece of PHP code that is executed when we perform access checking. The returning value of the code is used to determine if the role or assignment applies to the current user. In the example above, we associated a business rule with the updateOwnPost task. In the business rule we simply check if the current user ID is the same as the specified post's author ID. The post information in the $params array is supplied by developers when performing access checking.

Access Checking

To perform access checking, we first need to know the name of the authorization item. For example, to check if the current user can create a post, we would check if he has the permission represented by the createPost operation. We then call CWebUser::checkAccess to perform the access checking:

if(Yii::app()->user->checkAccess('createPost'))
{
    // create post
}

If the authorization rule is associated with a business rule which requires additional parameters, we can pass them as well. For example, to check if a user can update a post, we would do

$params=array('post'=>$post);
if(Yii::app()->user->checkAccess('updateOwnPost',$params))
{
    // update post
}

Using Default Roles

Note: The default role feature has been available since version 1.0.3

Many Web applications need some very special roles that would be assigned to every or most of the system users. For example, we may want to assign some privileges to all authenticated users. It poses a lot of maintenance trouble if we explicitly specify and store these role assignments. We can exploit default roles to solve this problem.

A default role is a role that is implicitly assigned to every user, including both authenticated and guest. We do not need to explicitly assign it to a user. When CWebUser::checkAccess is invoked, default roles will be checked first as if they are assigned to the user.

Default roles must be declared in the CAuthManager::defaultRoles property. For example, the following configuration declares two roles to be default roles: authenticated and guest.

return array(
    'components'=>array(
        'authManager'=>array(
            'class'=>'CDbAuthManager',
            'defaultRoles'=>array('authenticated', 'guest'),
        ),
    ),
);

Because a default role is assigned to every user, it usually needs to be associated with a business rule that determines whether the role really applies to the user. For example, the following code defines two roles, authenticated and guest, which effectively apply to authenticated users and guest users, respectively.

$bizRule='return !Yii::app()->user->isGuest;';
$auth->createRole('authenticated', 'authenticated user', $bizRule);
 
$bizRule='return Yii::app()->user->isGuest;';
$auth->createRole('guest', 'guest user', $bizRule);
$Id: topics.auth.txt 1808 2010-02-17 21:49:42Z qiang.xue $
If you found any typos or errors in the tutorial, please create a Yii ticket to report it. If it is a translation error, please create a Yiidoc ticket, instead. Thank you.

Total 21 comments:

#32
Why are getTitle/setTitle declared ?
by staun at 12:09am on December 28, 2008.

They cannot be called as they are not part of the interface or the class, so Yii::app()->user->getTitle() will never work.

#34
Re: Why are getTitle/setTitle declared ?
by aztech at 12:19pm on December 29, 2008.

getTitle() and setTitle() can't be called because they are method of UserIdentity class. Yii::app()->user is instance of CWebUser. So you can use declared title only like this: Yii::app()->getState('title');

#38
data for AuthItem && note on bizRule
by mindeh at 1:38am on January 7, 2009.

data: $auth->createRole() $auth->createOperation() $auth->createTask() all take $data as 3rd param - it is later serializaed and the data may be used in bizRule statement(s).

bizRule: it is executed using eval statement - see php.net/eval.

#78
Assign User to Multiple Groups
by br0sk at 2:53am on February 16, 2009.

Hi,

The RBAC seems to be very good and flexible. I have played around with it a bit. I noticed that you can assign several roles to a user at the same time. Does anybody know how this will affect the access right? Will one of the roles take precedence or will there be some kind of mix between the roles?

#119
RBAC Database Tables
by emix at 3:30pm on March 17, 2009.

If anyone is looking for RBAC table scheme it can be found at /framework/web/auth/schema.sql :)

#126
Mistake in example?
by sumwai at 3:56am on March 22, 2009.

$task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule);

doesn't works for me as in the example

$task=$auth->createOperation('...

works.

#179
Easier role-management
by pelleke at 4:56am on April 8, 2009.

Easier option for very simple role management

For my application I needed basic role-based authentication, but in a very simplistic way. The only thing I wanted to do more than what CUserIdentity limited me to, is making a difference between normal and admin users. These 'roles' are static in my application, and do not have the need to be changed in the production environment. I found the CAuthManager a little bit too complicated for this job, and I also think it would be nice to have the user role in the same database table as the user itself.

Here's what I did:

Database field

Start by adding an integer field in your users table for the role. I called mine 'kind'.

Role constants

Define some constants for your role like this:

class User extends CActiveRecord
{
    const ADMIN = 0, EDITOR=1;
    [...]


Validation

Make sure the role numbers in the table can't exceed the range

public function rules()
{
    return array(
        array('kind', 'in', 'range'=>range(0, 1)),
        [...]


Get all usernames by role

In your model PHP-file, create a public static function that extracts all the users of a certain role. My function looks like this, you might want to adjust some identifiers to match with your database's column names.

public static function usernamesByRole($role) {
    $users = User::model()->findAllByAttributes(array('kind'=>$role));
    $usernames = array();
    foreach ($users as $user) $usernames[] = $user->username;
    return $usernames;
}


Implementing the access control

In a certain controller where you want role-based access control, use the static function we just made to include the usernames.

public function accessRules()
{
    return array(
        array('allow', // allow authenticated user to perform 'create' and 'update' actions
            'actions'=>array('create','update'),
            'users'=>User::usernamesByRole(User::ADMIN), // Only administrators allowed!!!
        ),
        [...]

As I'm not a very experienced yii-devver, I'd like to see some thoughts/comments on this.

#198
Reply to pelleke's role management
by Vasiliy Naumov at 4:58am on April 15, 2009.

Regarding 'users'=>User::usernamesByRole(User::ADMIN) rule.

It seems to be very slow (especially when you have many users in your User table), because you have to select ALL users from database with given role and after it filter checks all this array for you current name.

I would make it otherwise: function should do something like following: 1. It needs one additional parameter - user ID. (which one you can get with Yii::app()->user->id - may be default value). 2. Function gets these two params, and checks if given user has this role. If succeded, it returns array(username), otherwise array().

In this case, your select will work much faster, because you have your primary key in where clause. And php will not have to check each user returned by function previously.

Hope it will help someone.

#215
Expanded upon pelleke's role management
by scythah at 4:31pm on April 20, 2009.

I really liked pelleke's methods for their simplicity, but I needed more than one role available.

// User Model File
const ADMIN = 3, EDITOR = 2, USER = 1

I've expanded on pelleke's role function to allow multiple roles to be requested. For me, this is because I have more than 2 roles that I'm defining.

// User Model file
/**
 * User::byRole(array(User::GROUP1,User::GROUP2))
 * @return array usernames in the specified group/s.
 */
public static function byRole($group) {
    $usernames = array();
    foreach ($group as $group_id):
        $users = User::model()->findAllByAttributes(array('group_id'=>$group_id));
        foreach ($users as $user) $usernames[] = $user->username;
    endforeach;
    return $usernames;
}

This then allows me to do the following:

// Controller file
public function accessRules()
{
    return array(
        array('allow', // allow authenticated user to perform 'create' and 'update' actions
            'actions'=>array('create','update'),
            'users'=>User::byRole(User::ADMIN, User::EDITOR), // Only administrators and editors allowed!!!
        ),
        [...]

I then also wanted a way to use this in the MainMenu widget so I made the following:

// User Model file
/**
 * User::getAuthByRole(array(User::GROUP1,User::GROUP2))
 * @return boolean whether the currently logged in user exists in the specified group/s
 */
public static function getAuthByRole($group) {
    $auth = false;
    foreach ($group as $group_id):
        $exists=User::model()->exists('id=:id AND group_id=:group_id',array(
            'id'=>Yii::app()->user->id,
            'group_id'=>$group_id)
        );
        if ($exists) {$auth=true;}
    endforeach;
    return $auth;
}

Which then allows me to use the MainMenu widget to allow show links to certain roles.

// Main Template File
<?php $this->widget('application.components.MainMenu',array(
    'items'=>array(
        array('label'=>'Home', 'url'=>'/', 'visible'=>!Yii::app()->user->isGuest),
        array('label'=>'Contact', 'url'=>array('/site/contact'), 'visible'=>Users::getAuthByRole(array(User::ADMIN,User::EDITOR,User::USER))),
        array('label'=>'User management', 'url'=>array('/users'), 'visible'=>Users::getAuthByRole(array(User::ADMIN))),
        array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
        array('label'=>'Logout', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
    ),
)); ?>

:)

#283
Reply to br0sk : Assign User to Multiple Groups
by kylian at 5:44am on May 13, 2009.

Br0sk, your question was : I noticed that you can assign several roles to a user at the same time. Does anybody know how this will affect the access right? ...

I found the answer in the class reference documentation: "A user is said to have a permission to do something if the corresponding authorization item is inherited by one of his roles." This seems clear.

#284
Another reply to to pelleke's role management
by kylian at 5:58am on May 13, 2009.

Pelleke, I do not understand why you return all the list of users with a certain role, instead of taking only the logged one in session. See my alternative method:

1 Define constants

class Users extends CActiveRecord
{
    const ROLE_READER=0;
    const ROLE_EDITOR=1;
    const ROLE_ADMIN=2;

2 Adapt the UserIdentity class

class UserIdentity extends CUserIdentity
{
    ...
    public function authenticate()
    {
        your code...
        // Extract informations from user, including role
        // (adapt according to your database)
        $record=Users::model()->findByAttributes(array('uid'=>"$uid"));
        your code...
if (user is athenticated...){ $this->errorCode=self::ERROR_NONE; your code... // Store the role with the setState method if (!($record===null)) { $this->setState('role', $record->role); } } your code... return !$this->errorCode; }

3 Include new rule in controlers

    public function accessRules()
    {
        return array(
            ...
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions'=>array('admin','delete'),
                'expression'=>'Yii::app()->user->getState("role")==Users::ROLE_ADMIN',
            ...

And its done.

#290
Reply to kylian
by m_goku at 5:25pm on May 14, 2009.

I used exactly the same method as yours

It work perfectly except that i don't know how to change the Unauthorized message.............

Well, there are still a lot for me to learn

#529
Reply to kylian
by SilentWarrior at 8:33am on August 2, 2009.

I am using the same exact way that kylian shared.

Except, that 'expression' he gave us looks kinda ugly, so I replaced it with :

class Users extends CActiveRecord { const STATUS_UNACTIVE=0; const STATUS_ACTIVE=1; const STATUS_GOLD=2; const STATUS_ADMIN=3; const STATUS_TEMPBAN=4; const STATUS_BANNED=5;

    public function checkRole($acessLevel){
        return Yii::app()->user->getState("accessLevel")==$acessLevel;
    }

And then calling it by : public function accessRules() { return array(

        array('allow', // allow admin user to perform 'admin' and 'delete' actions
            'actions'=>array('admin','delete'),
                            'expression'=>Users::checkRole(Users::STATUS_ADMIN),
        ),          
    );
}

#530
Markup error
by SilentWarrior at 8:34am on August 2, 2009.

Last comment went with ugly markup, can an admin fix that plz? (delete this after) thx

#581
Authentication
by pelleke at 8:30am on August 14, 2009.

Well, it seems my effort has been taken seriously. I like that.

@kylian @Vasiliy: I just made a little mistake in my thinking; I was thinking the access control list should include all users having access to a specific feature. Including only the user that's logged in at that moment just didn't come to my mind, wrong way of thinking, I guess.

#601
Different authentication for backend
by Virtual DarKness at 8:11pm on August 21, 2009.

If your app is divided in frontend and backend and you wish to have your admin user information stored in a different cookie, you have to change the backend's application name.

#737
Missing piece of information in CPhpAuthManager
by raslam at 10:27am on October 15, 2009.

Hi,

In the example of php based RBAC there is very important statement missing. Lack of which cause me trouble as I am new and others too, as they asked about it in forums.

$auth->save();

There is no mentioning of above statement and I am going nuts because the sample code isn't working.

So, please add the statement.

Thanks.

#775
check acces with beforeAction()
by bas_vdl at 10:37am on October 28, 2009.


    protected function beforeAction()
    {
        if(Yii::app()->user->checkAccess(ucfirst($this->getId()) . ucfirst($this->getAction()->getId())))
        {
            return true;
        } else {
            Yii::app()->request->redirect(Yii::app()->user->returnUrl);
        }
    }
#918
required?
by webscriptz at 12:27pm on December 20, 2009.

array('username'=>$this->username) do we have to use username because i user identityName as row in my table and I user it everywhere but when i try to let it work he doesn't want to accept it; i never use the variable username and yet he asks me that i use it, can anyone help me?

#1100
Too messy
by mintao at 2:01pm on February 12, 2010.

I'm a newbie when it comes to RBAC, but it really seems to be very flexible. In my opinion, this part of yii has to be cleaned up radically.

  1. I don't understand, why a user-id is the user name and why I manually have to fix it (I don't even have a username in my schema and it shouldn't be mandatory)
  2. I don't understand - when talking about roles, tasks and operations - why we grant roles in a controller
  3. I don't understand why the 3 Auth-tables use item as term

These 3 points don't make it easier for me to understand this great feature - beside to the fact that the schema isn't mentioned in the documentation ;) (yes, I already found it)

#1113
Top-down view...
by dcolley at 2:27am on February 15, 2010.

Reading the code above really got me confused. Turning the authorisation tree 'right way up' was more helpful to me when understanding the parent-child relationships between updateOwnPost and updatePost.

(Person) "AuthorB"

  • has (Role) author

(Role) author

  • has (Task) reader
  • has (Task|Operation) createPost
  • has (Task|Operation) updateOwnPost (i.e. where author_id = me) (1)

(Task) updateOwnPost

  • has (Operation) updatePost (2)

If you want users to be able update all posts, give them access to updatePost

If you want to allow users to update ONLY their OWN posts (i.e. via the Business Rule), then give them access to updateOwnPost (2)

So, traversing the access tree from the top you get through the gate called "updateOwnPost" if the condition is true. Note: you can't update anything yet. Only when you pass this gate do you fall through to "updatePost" - and this is where you get the actual permission to make an update.

Hence the contoller only needs to grant permission for update action to the updatePost role

Your Comment:

You may enter comment using Markdown syntax.

Please login with your forum account.
Note: you must have at least ONE forum post with your account.