开发者

ACL checks at API level, on a per-method basis

I'm working on a sort of MVC framework, and I'm implementing a simple ACL permissions check system.

I'm wondering if anyone can shed some light on, or direct me towards some good examples of this sort of implementation (or criticize to the point of warranting scrapping it, whichever is necessary)

Since I'm building the framework with REST API in mind, I've created two base controllers, WebController and ApiController.

Requests made to /index.php route to WebController_* and requests made to /api/index.php route to ApiController_*

An extended WebController is responsible for building output from a template with data returned from the consolidated calls to the necessary ApiControllers.

An extended ApiController is responsible for querying the Model for data. If a call is made directly to /api/index.php it returns JSON.

But I digress; In order to facilitate ACL, I figured implementi开发者_运维百科ng it at the ApiController layer made sense, and if there is a denial it is returned in JSON or back up to a WebController and handled accordingly, depending on the request type.

I'm thinking to simplify things, I could make use of __call() and private methods. __call() would verify the existence of the requested method, and prior to calling it, check the user permissions on the method it against the 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
        }
    }

}

Good idea? Bad idea? Thoughts? Maybe I'm in over my head here, I'm still learning and this is more for education than profit, however finishing something that has future use would be nice.


This is a pretty good idea to check credentials in the ApiController layer but try to kill the magic by avoiding the __call() method. Yes, this isn't your question but could be useful if you want better performances.

Well, you may use filters like a security filter which handles the request and check the user permissions. The filter could redirect the request to the 401 error response for example. This idea comes from the Symfony Framework.

Regards, William.


I've decided to go with an approach similar to my initially proposed method, creating a Gateway object to act as a proxy to the Model. Essentially the Gateway object holds a reference to the Acl, Request, and Model objects, and performs checks against the Acl object before forwarding any method calls to the Model. Simplified for brevity:

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;
}

Are there any issues that can be seen with this approach? So far as I can tell, this should serve the purpose quite effectively, as I can sub in different Acl and Model objects based on the needs of the Controller (Though likely there will only be the need for a single Acl)

Furthermore, my routing of API calls becomes simplified, as using a REST/RPC hybrid architecture, API calls can be passed to the Gateway without much need for modification.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜