在 API 级别按方法进行 ACL 检查

发布于 2024-10-19 12:47:34 字数 1422 浏览 0 评论 0原文

我正在开发一种 MVC 框架,并且正在实现一个简单的 ACL 权限检查系统。

我想知道是否有人可以阐明,或者指导我一些此类实现的好例子(或者批评到需要废弃它的程度,无论哪一个是必要的),

因为我正在使用 REST API 构建框架请注意,我创建了两个基本控制器:WebControllerApiController

/index.php 发出的请求路由至 WebController_*,对 /api/index.php 发出的请求路由至 ApiController_*< /code>

扩展的 WebController 负责从模板构建输出,并使用从对必要的 ApiController 的合并调用返回的数据。

扩展的 ApiController 负责查询 Model 中的数据。如果直接调用 /api/index.php,它将返回 JSON

但是我离题了;为了促进 ACL,我认为在 ApiController 层实现它是有意义的,如果存在拒绝,则会以 JSON 返回/code> 或备份到 WebController 并根据请求类型进行相应处理。

我想简化事情,我可以使用 __call()private 方法。 __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
        }
    }

}

好主意?坏主意?有什么想法吗?也许我有点不知所措,我仍在学习,这更多的是为了教育而不是为了利润,但是完成一些将来有用的东西会很好。

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 implementing 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不忘初心 2024-10-26 12:47:34

ApiController 层中检查凭据是一个非常好的主意,但尝试通过避免使用 __call() 方法来消除魔力。是的,这不是您的问题,但如果您想要更好的性能,这可能会很有用。

那么,您可以使用过滤器,例如安全过滤器,它处理请求并检查用户权限。例如,过滤器可以将请求重定向到 401 错误响应。
这个想法来自 Symfony 框架

问候,
威廉.

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.

从此见与不见 2024-10-26 12:47:34

我决定采用与我最初提出的方法类似的方法,创建一个 Gateway 对象来充当 Model 的代理。本质上,Gateway 对象保存对 AclRequestModel 对象的引用,并针对在将任何方法调用转发到 Model 之前,Acl 对象。为简洁起见,进行了简化:

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 调用可以传递到网关,而不需要太多修改。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文