API中的用户权限控制

2018-11-14  本文已影响0人  Ethan遗忘

需求

服务器处理用户对资源进行增删改查的请求时,需要判断该用户是否有权限进行相应的操作:

POST
* 该用户是否有权限创建此类资源?

GET
* 该用户是否有权限查询此类资源的权限?
* 如果是查询指定ID的资源,那么该用户是否有查询该资源的权限?

PUT
* 该用户是否有更新该资源的权限?

DELETE
* 该用户是否有删除该资源的权限?

解决方案

通过oslo_policy库实现RBAC。RBAC是指基于角色的访问控制模型,在该模型中,包含四类对象:用户、角色、许可、会话。一个用户可以有多个角色,一个用户可以发起多个会话,每个角色拥有对某些特定资源的特定访问权限。

实践

Role:通过用户的Token判断用户的角色

Rule:在配置文件中预定义访问规则(WHO-WHAT-HOW),程序启动时加载规则。

三个租户ID:一般控制器会带有一个Context上下文对象,Context对象又带有一个Session会话对象,Session对象中带有用户请求的token,token中带有租户ID;一般请求的URL中会带有租户的ID;如果是一个GET或PUT请求,所请求的资源一般也会有一个租户ID字段,需要校验三个租户ID是否一致。(这里倒不是RBAC,而是出于安全的考虑,一个租户不能越权访问到另一个租户的资源)

在每个类型资源的控制器中添加控制逻辑:

  1. 指定本身资源类型
self.RBAC_TYPE = const.RESOURCE_TYPE_A
  1. POST
    • 该用户是否有权限创建此类资源?
      self._auth_check_action(context.session, self.project_id, const.RBAC_POST)
      
  2. GET
    • 该用户是否有权限查询此类资源的权限?
    • 如果是查询指定ID的资源,那么该用户是否有查询该资源的权限?
      db_obj = self._get_db_obj(id)
      self._auth_check_action(context.session, db_obj.project_id, const.RBAC_GET_ONE)
      # self._auth_check_action(context.session, db_obj.project_id, const.RBAC_GET_ALL)
      
  3. PUT
    • 该用户是否有更新该资源的权限?
      db_obj = self._get_db_obj(id)
      self._auth_check_action(context.session, db_obj.project_id, const.RBAC_PUT)
      
  4. DELETE
    • 该用户是否有删除该资源的权限?
      db_obj = self._get_db_obj(id)
      self._auth_check_action(context.session, db_obj.project_id, const.RBAC_DELETE)
      

其他注意点

  1. 查询数据库里的记录时,为什么不指定租户ID进行查询?
    这样可以实现超级管理员的功能(如果指定租户ID进行查询,那么“超级管理员”就查询不到所有资源了)。
  2. Token中的租户ID和URL中的租户ID是否匹配,应该在Controller初始化时就统一进行校验,而不是每个Controller分别进行实现或调用,在Controller中进行的校验主要是:资源的所属的租户ID与请求token(或url)中的租户ID是否匹配以及RBAC。
上一篇下一篇

猜你喜欢

热点阅读