Yii Framework Official Guide Series 42-topics: verification and authorization

Source: Internet
Author: User
Tags php session
We need to use Authentication and Authorization for webpages that require access restriction by some users ). Verification refers to checking whether a person is actually the one he claims. This usually requires a user...



We need to use Authentication and Authorization for webpages that require access restriction by some users ). Verification refers to checking whether a person is actually the one he claims. This usually requires a user name and password, but it also includes any other methods that can indicate the identity, such as a smart card or fingerprint. Authorization is to identify whether verified users are allowed to operate on specific resources. This is generally determined by querying whether the user belongs to a role with the right to access the resource.

Yii has a built-in authentication/authorization framework, which is easy to use and can be customized to meet special requirements.

The core of the Yii auth framework is a predefinedUser application componentIt is an object that implements the IWebUser interface. This user component represents the persistent authentication information of the current user. We can useYii::app()->userAccess it anywhere.

Using this user component, we can use CWebUser: isGuest to check whether a user is logged in. you can log in or log out as a user. we can use CWebUser :: checkAccess checks whether the user can perform specific operations. It can also obtain the unique identity (unique identifier) and other persistent identity information of the user.

1. Defining Identity Class)

To verify a user, we define an identity class with authentication logic. This identity class implements the IUserIdentity interface.

Different classes may implement different authentication methods (such as OpenID and LDAP ). It is best to inherit CUserIdentity, which is the authentication method of the user name and password.

The main task of defining the identity class is to implement the IUserIdentity: authenticate method. Identity classes may need to define other identity information as needed in user sessions

Application instance

In the following example, we use Active Record to verify whether the provided user name and password match the database user table. By rewritinggetIdFunction to return_idVariable (the default implementation is to return the user name ). During verification, we also use the CBaseUserIdentity: setState function to obtaintitleInformation is saved to a status.

  1. The implementation ofauthenticate()To use the database to validate credentials.

  2. OverridingCUserIdentity::getId()Method to return_idProperty because the default implementation returns the username as the ID.

  3. UsingsetState()(CBaseUserIdentity: setState) method to demonstrate storing other information that can be easily be retrieved upon subsequent requests.



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 as status (by calling CBaseUserIdentity: setState) will be passed to CWebUser. The latter stores the information on a permanent storage media (such as session ). We can use this information as a CWebUser attribute. For exampletitleInformation, we can useYii::app()->user->title(This feature was introduced in version 1.0.3. In earlier versions, we need to useYii::app()->user->getState('title')).

Tip:By default, CWebUser uses session to store user identity information. If you allow cookie-based login (by setting CWebUser: allowAutoLogin to true), the user identity information will be stored in the cookie. Do not store sensitive information (such as password ).

2. Login and Logout)

Using identity classes and user components, we can easily log on and log off.



// Use the provided username and password to log on to the user $ identity = new UserIdentity ($ username, $ password); if ($ identity-> authenticate () Yii: app () -> user-> login ($ identity); else echo $ identity-> errorMessage ;...... // log off the current user Yii: app ()-> user-> logout ();


Here we are creating a new UserIdentity object and passing in the authentication credentials (I. e.$usernameAnd$passwordValues submitted by the user) to its constructor. We then simply callauthenticate()Method. if successful, we pass the identity information into the CWebUser: login method, which will store the identity information into persistent storage (PHP session by default) for retrieval upon subsequent requests. if the authentication fails, we can interrogateerrorMessageProperty for more information as to why it failed.

Whether or not a user has been authenticated can easily be checked throughout the application by usingYii::app()->user->isGuest. If using persistent storage like session (the default) and/or a cookie (discussed below) to store the identity information, the user can remain logged in upon subsequent requests. in this case, we don't need to use the UserIdentity class and the entire login process upon each request. rather CWebUser will automatically take care of loading the identity information from this persistent storage and will use it to determine whetherYii::app()->user->isGuestReturns true or false.

Cookie-based logon

By default, the user logs out after completing a series of inactivity actions based on the session configuration. Set the allowAutoLogin attribute of the user part to true and set a duration parameter in the CWebUser: login method to change this behavior. Even if the user closes the browser, the user will keep the user login status for the set duration. The premise is that your browser accepts cookies.



// Retain the user logon status for 7 days // ensure that the allowAutoLogin of the user part is set to true. Yii: app ()-> user-> login ($ identity, 3600*24*7 );


As we mentioned above, when cookie-based login is enabled, the states stored viaCBaseUserIdentity: setState will be saved in the cookie as well. the next time when the user is logged in, these states will be read from the cookie and made accessibleYii::app()->user.

Although Yii has measures to prevent the state cookie from being tampered on the client side, we stronugly suggest that security sensitive information be not stored as states. instead, these information shoshould be restored on the server side by reading from some persistent storage on the server side (e.g. database ).

In addition, for any serious Web applications, we recommend using the following strategy to enhance the security of cookie-based login.

  • When a user successfully logs in by filling out a login form, we generate and store a random key in both the cookie state and in persistent storage on server side (e.g. database ).

  • Upon a subsequent request, when the user authentication is being done via the cookie information, we compare the two copies of this random key and ensure a match before logging in the user.

  • If the user logs in via the login form again, the key needs to be re-generated.

By using the above strategy, we eliminate the possibility that a user may re-use an old state cookie which may contain outdated state information.

To implement the above strategy, we need to override the following two methods:

  • CUserIdentity: authenticate (): this is where the real authentication is already Med. if the user is authenticated, we shoshould re-generate a new random key, and store it in the database as well as in the identity states via CBaseUserIdentity: setState.

  • CWebUser: beforeLogin (): this is called when a user is being logged in. We shoshould check if the key obtained from the state cookie is the same as the one from the database.

3. Access Control Filter)

The ram filter is the initial authorization mode for checking whether the current user can execute the access controller action. This authorization mode is based on the user name, customer IP address, and access type. it is provided in the form of a filter named "accessControl.

Tips:The access control filter applies to simple verification. Complex access control is required. you need to use the role-based access control (RBAC) to be explained )).

In the controller, reload the CController: filters method to set the access Filter to control the access action (see Filter for more information on Filter settings ).



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


In the preceding example, the access control filter is appliedPostController. The specific authorization rules of the filter are specified by the CController: accessRules method of the overload Controller.



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('*'),            ),        );    }}


Three rules are set above, each of which is represented by an array. The first element of the array is not'allow'Yes'deny'The others are in the form of name-value pairs to set rule parameters. The above rules are as follows:createAndeditThe action cannot be executed anonymously;deleteActions can beadminRole user execution;deleteThe action cannot be executed by anyone.

Access rules are judged one by one in the set order. The authorization result is determined by the first rule that matches the current judgment mode (for example, user name, role, client IP address, and address. If this rule isallow, The action can be executed.denyAnd cannot be executed. If no rule matches, the action can be executed.

Info | tip: to ensure that an action is not executed without permission, setdenyThe rule is similar to the following at the end:



Return array (//... other rules... // the following matches all rules to reject the 'delete' action array ('Deny', 'Action' => 'Delete ',),);


If no rule matching action is set, the action is executed by default.

Access rules are set using the following context parameters:

  • Actions: specifies the action that matches this rule.

  • Users: Set the user to match this rule. The name of the current user is used to match. three character types can be used here:

    • *: Any user, including anonymous and authenticated users.

    • ?: Anonymous user.

    • @: Verified user.

  • Roles: set which role matches this rule. The role-based access control technology described later is used here. In particle, the rule is applied if CWebUser: checkAccess returns true for one of the roles. the prompt is that the user role should be setallowRule, because a role can do something.

  • Ips: set which client IP address matches this rule.

  • Verbs: specifies the request type (for example:GET,POST) Match this rule.

  • Expression: set a PHP expression. The value indicates whether the rule applies. In an expression, you can use$userVariable, which representsYii::app()->user. This option is introduced in version 1.0.3.

Handling Authorization Result)

When the authorization fails, that is, the user is not allowed to perform this action, the following two may be generated:

  • If the user has not logged on and configured loginUrl in the user part, the browser will relocate the webpage to this configuration URL.

  • Otherwise, an HTTP exception with error code 401 is displayed.

When configuring the loginUrl attribute, you can use relative and absolute URLs. You can also use arrays to generate URLs through CWebApplication: createUrl. The first element sets route as the logon controller action, and other GET parameters in the form of-values pairs. As follows,



Array (...... 'components' => array ('user' => array (// This is actually the default value 'loginurl' => array ('site/login '),),),)


If the browser is relocated to the logon page and the logon succeeds, we will relocate the browser to the page that causes verification failure. How do we know this value? We can use the returnUrl attribute of the user part. Therefore, we can use the following to execute redirection:



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


4. Role-Based Access Control)

Role-Based Access Control provides a simple and powerful centralized access control. See Wikipedia for more information on the comparison between RBAC and other traditional access control modes.

Yii implements a hierarchical RBAC structure through its authManager component. In the following section, we will first introduce the main concepts used in this structure. Then explains how to define the data used for authorization. Finally, let's take a look at how to use the authorized data to perform access checks.

Overview)

In RBAC of Yii, a basic concept isAuthorization item). An authorized project is a license for doing something (such as publishing new posts and managing users ). According to its granularity and target audience, authorized projects can be dividedOperations),Task)AndRole). A role is composed of several tasks. a task consists of several operations. an operation is a license and cannot be divided. For example, we have a system that hasAdministratorRole, which consistsPost managementAndUser ManagementTask composition.User ManagementThe task can containCreate User,Modify userAndDelete a userOperation composition. To maintain flexibility, Yii also allows a role to include other roles or operations. a task can include other operations. one operation can include other operations.

An authorized project is uniquely identified by its name.

An authorization project may be associated withBusiness rulesAssociation. A business rule is a piece of PHP code that will be executed during access checks involving authorized projects. Only when true is returned will the user be deemed to have the permission represented by this authorization project. For exampleUpdatePost (update Post)During operations, we can add a business rule to check whether the current user ID is the same as the Post author ID, so that only the author himself has the permission to update the post.

By authorizing a project, we can buildAuthorization level system. In the hierarchy, if the projectABy another projectBComposition (orAInheritedB), ThenAYesB. An authorized project can have multiple sub-projects or multiple parent projects. Therefore, the authorization level system is a partial-order graph structure rather than a tree structure. In this hierarchy, the role Project is located at the top level, the operation project is located at the bottom level, and the task Project is located between the two.

Once we have an authorization level system, we can assign roles in this system to users. Once a user is assigned a role, the user will have the permissions represented by this role. For example, if we assign a userAdministratorThe role will have the administrator's permissions, includingPost managementAndUser Management(And related operations, suchCreate User).

Now the interesting part begins. in a controller action, we want to check whether the current user can delete the specified Post. With RBAC level system and allocation, this can be easily achieved. As follows:



If (Yii: app ()-> user-> checkAccess ('deletepost') {// delete this post}


5. configure Authorization Manager)

Before defining an authorization level system and performing an access permission check, we need to configure the authManager application component. Yii provides two authorization managers: CPhpAuthManager and CDbAuthManager. The former stores the authorized data in a PHP script file and the latter in the database. When configuring the authManager application component, we need to specify which Authorization Manager component class to use and the initialization attribute value of the selected authorization manager component. For example:



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


Then, we can useYii::app()->authManagerAccess the authManager application component.

6. define the authorization level system

Define the authorization level body in three steps: define the authorization project, establish the relationship between authorization projects, and assign roles to users. The authManager application component provides a series of APIs for completing these three tasks.

To define an authorization project, you can call one of the following methods, depending on the project type:

  • CAuthManager: createRole

  • CAuthManager: createTask

  • CAuthManager: createOperation

After creating an authorized project, we can call the following methods to establish the relationship between authorized projects:

  • CAuthManager: addItemChild

  • CAuthManager: removeItemChild

  • CAuthItem: addChild

  • CAuthItem: removeChild

Finally, we call the following method to assign the role to the user.

  • CAuthManager: assign

  • CAuthManager: revoke

The following code demonstrates an example of using APIs provided by Yii to build an authorization system:


$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');$auth->save();


Note: If the getId method is not rewritten in UserIdentity, the assign is correct. if getId is rewritten, the user Id is returned, then the corresponding user name should be modified to the corresponding user ID in the assign statement, otherwise it will be invalid when the checkAccess method is used!

After this authorization level system is established, the authManager component (such as CPhpAuthManager and CDbAuthManager) automatically loads the authorization project. Therefore, we only need to run the above code once, and do not need to run in every request.

Information:The above example seems to be lengthy, and is mainly used for demonstration purposes. Developers usually need to develop some user interfaces for management, so that end users can establish an authorization level system more intuitively through the interface.

7. use business rules

When defining the authorization level system, we canBusiness rulesAssociate a role, a task, or an operation. We can also associate a business rule when assigning a role to a user. A business rule is a piece of PHP code that is executed when we perform a permission check. The value returned by the code is used to determine whether to apply a role or assign it to the current user. In the above example, we associate a business ruleupdateOwnPostTask. In business rules, we simply check whether the current user ID is the same as the author ID of the specified Post.$paramsThe post information in the array is provided by the developer during permission check.

Permission check

To perform a permission check, we first need to know the name of the authorization project. For example, to check whether the current user can create a post, we need to check whether the user hascreatePostIndicates the permission. Then we call CWebUser: checkAccess to perform the permission check:



If (Yii: app ()-> user-> checkAccess ('createpost') {// Create Post}


If an authorization rule is associated with a business rule that requires additional parameters, it can also be passed to it. For example, to check whether a user can update a post, we can$paramsTransmit Post data:



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


Use default roles

Note:The default role function is available from version 1.0.3.

Many Web programs require special roles that can be assigned to all or most users in the system. For example, we may want to assign some permissions to all authenticated users. If we specifically specify and store these role assignments, it will cause a lot of maintenance troubles. We can useDefault roleSolve this problem.

The default role is a role that is implicitly assigned to each user. these users include authenticated users and visitors. We do not need to explicitly allocate it to a user. When CWebUser: checkAccess is called, the default role is checked first, just as it has been assigned to this user.

The default role must be defined in the CAuthManager: defaultRoles attribute. For example, the following configuration declares two roles as default roles:authenticatedAndguest.



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


Because the default role is assigned to each user, it usually needs to associate a business rule to determine whether the role is actually applied to the user. For example, the following code defines two roles,authenticatedAndguestIt is very efficient to apply to users who have passed identity authentication and visitors 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);


The above is the Yii Framework Official Guide Series 42-topic: verification and authorization content. For more information, please follow the PHP Chinese network (www.php1.cn )!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.