如何同时使用控制器和操作授权

时间:2013-05-22 20:39:25

标签: cakephp controller authorization acl

我是cakephp的新手,我正试图从头开始构建一个应用程序。我正在阅读手册,我也做了教程。

现在我面临着一个关于授权的问题:如何允许用户执行操作(编辑,删除......),但只有当它们是他们自己的事物(帖子,事件......)时,才使用ActionsAuthorize和控制器同时授权。也许这是一个愚蠢的问题,但作为一个新手,我觉得我错过了一些东西。

如果应用程序更简单,仅使用ControllersAuthorize(isAuthorized())就足够了,但我发现ActionsAuthorize非常有用。

按照教程(博客)中的示例,每个帖子都有一个作者(用户)并且属于个人资料(作者,管理员,编辑......),用户一般都可以编辑帖子($ this-> Acl->允许('作者','控制器/帖子/编辑'))但只有他们自己的帖子。

到目前为止,我有以下代码:

//User Model
public $actsAs = array('Acl' => array('type' => 'both'));
public $belongsTo = array(
    'Profile' => array(
        'className' => 'Profile',
        'foreignKey' => 'profile_id'
    )
);
//saving the aro alias => username   
public function aftersave($created) {
    if($created) {
        $this->Aro->save(array('alias'=>$this->data[$this->alias]['username']));
    }
}

public function parentNode() {
    if (!$this->id && empty($this->data)) {
        return null;
    }
    if (isset($this->data['User']['profile_id'])) {
        $profileId = $this->data['User']['profile_id'];
    } else {
        $profileId = $this->field('profile_id');
    }
    if (!$profileId) {
        return null;
    } else {
        return array('Profile' => array('id' => $profileId));
    }
}

//Profile Model
public $actsAs = array('Acl' => array('type' => 'both'));
public function parentNode() {
    return null;
}
//savin the aco alias => name
public function aftersave($created) {
    if($created) {
        $this->Aro->save(array('alias'=>$this->data[$this->alias]['name']));
    }
}

//Post Model
public function isOwnedBy($post, $user) {
    return $this->field('id', array('id' => $post, 'user_id' => $user)) === $post;
}

//Post Controller
public function beforeFilter() {
    parent::beforeFilter();
    $this->Auth->allow('index');
}       
public function isAuthorized($user) {
    // All registered users can add posts
    if ($this->action === 'add' && isset($user)) {
        return true;
    }
    // The owner of a post can edit and delete it
    if (in_array($this->action, array('edit', 'delete'))) {
        $postId = $this->request->params['pass'][0];
        if ($this->Post->isOwnedBy($postId, $user['id'])) {
            //after knowing if the post is owned by the user check ACL
            return $this->Acl->check($user['profile_id'],$this->Acl->aco,$this->action);
        }
    }
    return parent::isAuthorized($user);
}

//AppController
public $components = array(
    'Acl',
    'Session',
    'Auth' => array(
        'authenticate' => array('Blowfish'),
        'authError' => 'You are not allow to perform this action, please login',
        'loginRedirect' => array('controller' => 'users', 'action' => 'login'),
        'logoutRedirect' => array('controller' => 'posts', 'action' => 'index')
    )
);
public function isAuthorized($user) {
    // Only admins can access admin functions
    if (isset($user['profile_id']) && isset($this->request->params['admin'])) {
        return (bool)($user['profile_id'] === '1');
    }
    // Admin can access every action
    if (isset($user['profile_id']) && $user['profile_id'] === '1') {
        return true;
    }       
    return false;
}       
public function beforeFilter() {
    $this->Auth->authorize = array('Controller');
    $this->Auth->allow('display');
}  
        // The owner of a post can edit and delete it
        if (in_array($this->action, array('edit', 'delete','view'))) {
            $postId = $this->request->params['pass'][0];
            if ($this->Post->isOwnedBy($postId, $user['id'])) {
                return $this->Acl->check($user['profile_id'],$this->Acl->aco,$this->action);
            }
        }
        return parent::isAuthorized($user);
    }

所以我的问题是,如果我在PostController中使用它的方式正确使用了授权:isAutorized():首先检查用户是否拥有该帖子,然后检查用户是否允许该操作。这是另一种方式吗?这种方式好吗?还有更好的方法吗?我错过了什么吗?

提前非常感谢!!

1 个答案:

答案 0 :(得分:0)

这是完成任务的一种方法。 编辑:已实现您正在进行ACL应用程序。如果你不是,这就是答案。认为它仍然可能有用,因为没有其他人回应。

public function doStuff(){
      if(AuthComponent::user('role') == 'admin'){
      //do stuff 
      }elseif(AuthComponent::user('id') == $blogpost['Blog']['owner']){ 
      // do stuff 
      }else{ 
      $this->Html->redirect(array('action' => 'elsewhere'));
      }


 }