zoukankan      html  css  js  c++  java
  • phalcon——访问控制列表ACL

    一个完整的使用实例(将acl封装成一个插件使用):

    use PhalconAcl;
    use PhalconAclRole;
    use PhalconAclResource;
    use PhalconEventsEvent;
    use PhalconMvcUserPlugin;
    use PhalconMvcDispatcher;
    use PhalconAclAdapterMemory as AclList;
    
    class SecurityPlugin extends Plugin
    {
        //返回一个已存在的或新创建的acl列表
        public function getAcl()
        {
            if(!isset($this->persistent->acl)) {
    
                $acl = new AclList();
                //设置默认访问级别为“拒绝”
                $acl->setDefaultAction(Acl::DENY);
    
                //添加角色
                $roles = array(
                    'users' => new Role('Users'),
                    'guests' => new Role('Guests')
                );
                foreach($roles as $role) {
                    $acl->addRole($role);
                }
    
                //添加私有资源
                $privateResources = array(
                    'posts' => array('post'),
                    'comments' => array('comment')
                );
                foreach($privateResources as $resource => $actions) {
                    $acl->addResource(new Resource($resource),$actions);
                }
    
                //添加公有资源
                $publicResources = array(
                    'index' => array('index'),
                    'register' => array('index'),
                    'login' => array('index','start','end'),
                    'posts' => array('index','detail')
                );
                foreach($publicResources as $resource => $actions) {
                    $acl->addResource(new Resource($resource),$actions);
                }
    
                //公有资源访问控制
                foreach($roles as $role) {
                    foreach($publicResources as $resource => $actions) {
                        foreach($actions as $action) {
                            $acl->allow($role->getName(),$resource,$action);
                        }
                    }
                }
    
                //私有资源访问控制
                foreach($privateResources as $resource => $actions) {
                    foreach($actions as $action) {
                        $acl->allow('Users',$resource,$action);
                    }
                }
                $this->persistent->acl = $acl;
            }
            return $this->persistent->acl;
        }
    
        //查询acl列表进行权限控制
        public function beforeDispatch(Event $event,Dispatcher $dispatcher)
        {
            $auth = $this->session->get('auth');
            if(!$auth) {         //查询当前用户的身份
                $role = 'Guests';
            } else {
                $role = 'Users';
            }
    
            $controller = $dispatcher->getControllerName();
            $action = $dispatcher->getActionName();
    
            $acl = $this->getAcl();
    
            $allowed = $acl->isAllowed($role,$controller,$action);
    
            if($allowed != Acl::ALLOW) {        //需要用户登录才有权限
                $dispatcher->forward(array(
                    'controller' => 'login',
                    'action'     => 'index'
                ));
                $this->session->destroy();
                return false;
            }
        }
    }
    
    在注入调度控制器时绑定到一个事件控制器中:
    $di->set('dispatcher',function() use ($di) {
    
        $eventsManager = new EventsManager;
    
        $eventsManager->attach('dispatch:beforeDispatch',new SecurityPlugin);
    
        $dispatcher = new Dispatcher;
        $dispatcher->setEventsManager($eventsManager);
    
        return $dispatcher;
    });

    这样每次从一个方法跳转到另一个方法之前程序都会先去查询一下权限控制列表,看看用户对即将跳转的方法是否有访问权限,若没有权限则跳转到插件中指定的方法。

    此外,还可以使用继承机制来构造更复杂的角色,只需要在添加角色的函数的第二个参数中写上要继承的那个角色的实例即可:

    // 创建角色

    $roleAdmins = new Role("Administrators", "Super-User role");

    $roleGuests = new Role("Guests");

    // 添加 "Guests" 到 ACL

    $acl->addRole($roleGuests);

    // 使Administrators继承Guests的访问权限

    $acl->addRole($roleAdmins, $roleGuests);

    为了提高性能, PhalconAcl 的实例可以被实例化到APC, session, 文本或数据库中:

     // 保存实例化的数据到文本文件中

     file_put_contents("app/security/acl.data", serialize($acl));

     // 返序列化

    $acl = unserialize(file_get_contents("app/security/acl.data"));

  • 相关阅读:
    降龙十八掌之三:(见龙在田)优化查询性能
    完整的项目工程目录结构
    降龙十八掌之一:(亢龙有悔)SQL Server Profiler和数据库引擎优化顾问
    ASP.NET状态管理的总结
    LINQ 图解
    获取IP城市
    Eclipse 编译StanfordNLP
    Centos JAVA Eclipse
    关掉PUTTY后,进程仍可以运行。
    centos lnmp 安装笔记
  • 原文地址:https://www.cnblogs.com/wujuntian/p/4694352.html
Copyright © 2011-2022 走看看