Проверки ACL на уровне API для каждого метода - PullRequest
0 голосов
/ 01 марта 2011

Я работаю над своего рода MVC-фреймворком и внедряю простую систему проверки прав доступа ACL.

Мне интересно, может ли кто-нибудь пролить свет или направить меня к чему-то хорошему?примеры реализации такого рода (или критиковать до такой степени, чтобы оправдать ее отмену, в зависимости от того, что необходимо)

Поскольку я создаю среду с учетом REST API, я создал два базовых контроллера, WebController и ApiController.

Запросы на /index.php маршрут к WebController_* и запросы на /api/index.php маршрут к ApiController_*

За расширение WebController отвечает за сборкувывод из шаблона с данными, возвращенными из консолидированных вызовов к необходимым ApiController с.

Расширенный ApiController отвечает за запрос к Model для данных.Если вызов сделан прямо на /api/index.php, он возвращает JSON.

Но я отвлекся; Чтобы облегчить ACL, я решил, что реализация его на уровне ApiController имеет смысли если есть отказ, он возвращается в JSON или обратно в WebController и обрабатывается соответственно, в зависимости от типа запроса.

Я думаю, чтобы упростить вещи, я мог бы использовать__call() и частных методов.__call() проверит существование запрошенного метода, и перед его вызовом проверьте права доступа пользователя к методу с ACL.

class ApiController{

    public function __call($method, $arguments){
        if(method_exists($this, $method)){
            //haven't written ACL classes yet, but something like this
            if(ACL::check(...)){ 
                return call_user_func_array(array($this, $method), $arguments);
            }else{
                return false;
            }
        }else{
            //throw catchable exception or something
        }
    }

}

Хорошая идея?Плохая идея?Мысли? Может быть, я здесь над головой, я все еще учусь, и это больше для образования, чем для прибыли, однако было бы неплохо закончить что-то, что будет использоваться в будущем.

Ответы [ 2 ]

1 голос
/ 01 марта 2011

Это неплохая идея проверить учетные данные в слое ApiController, но попытаться убить магию, избегая метода __call(). Да, это не ваш вопрос, но он может быть полезен, если вы хотите улучшить свои показатели.

Ну, вы можете использовать фильтры , например, фильтр безопасности , который обрабатывает запрос и проверяет разрешения пользователя. Например, фильтр может перенаправить запрос в ответ об ошибке 401. Эта идея взята из Symfony Framework .

С уважением, Уильям.

0 голосов
/ 19 марта 2011

Я решил пойти с подходом, аналогичным моему первоначально предложенному методу, создав объект Gateway, который будет действовать как прокси для Model.По существу, объект Gateway содержит ссылку на объекты Acl, Request и Model и выполняет проверку объекта Acl перед перенаправлением любых вызовов методов на Model.Упрощенно для краткости:

public function __call($method, $arguments){
    // check request data against acl
    if($this->_acl->check($this->_request, $method, $arguments)){
        // on success, send request in and forward method to model
        $this->_model->setRequest($this->_request);
        return call_user_func_array(array($this->_model, $method), $arguments);
    }
    // acl check failed, no access
    return false;
}

Есть ли какие-либо проблемы, которые можно увидеть при таком подходе? Насколько я могу судить, это должно служить цели достаточно эффективно, поскольку я могув различных объектах Acl и Model в зависимости от потребностей Controller (хотя, вероятно, потребуется только один Acl)

Более того, моя маршрутизация вызовов API упрощаетсяПри использовании гибридной архитектуры REST / RPC вызовы API могут передаваться на Gateway без особых изменений.

...