需求
服務(wù)器處理用戶對資源進行增刪改查的請求時刃永,需要判斷該用戶是否有權(quán)限進行相應(yīng)的操作:
POST
* 該用戶是否有權(quán)限創(chuàng)建此類資源茅撞?
GET
* 該用戶是否有權(quán)限查詢此類資源的權(quán)限煮落?
* 如果是查詢指定ID的資源,那么該用戶是否有查詢該資源的權(quán)限嚎莉?
PUT
* 該用戶是否有更新該資源的權(quán)限?
DELETE
* 該用戶是否有刪除該資源的權(quán)限佃蚜?
解決方案
通過oslo_policy庫實現(xiàn)RBAC。RBAC是指基于角色的訪問控制模型着绊,在該模型中谐算,包含四類對象:用戶、角色归露、許可洲脂、會話。一個用戶可以有多個角色靶擦,一個用戶可以發(fā)起多個會話腮考,每個角色擁有對某些特定資源的特定訪問權(quán)限雇毫。
實踐
Role:通過用戶的Token判斷用戶的角色
Rule:在配置文件中預(yù)定義訪問規(guī)則(WHO-WHAT-HOW)玄捕,程序啟動時加載規(guī)則。
三個租戶ID:一般控制器會帶有一個Context上下文對象棚放,Context對象又帶有一個Session會話對象枚粘,Session對象中帶有用戶請求的token,token中帶有租戶ID飘蚯;一般請求的URL中會帶有租戶的ID馍迄;如果是一個GET或PUT請求,所請求的資源一般也會有一個租戶ID字段局骤,需要校驗三個租戶ID是否一致攀圈。(這里倒不是RBAC,而是出于安全的考慮峦甩,一個租戶不能越權(quán)訪問到另一個租戶的資源)
在每個類型資源的控制器中添加控制邏輯:
- 指定本身資源類型
self.RBAC_TYPE = const.RESOURCE_TYPE_A
- POST
- 該用戶是否有權(quán)限創(chuàng)建此類資源赘来?
self._auth_check_action(context.session, self.project_id, const.RBAC_POST)
- 該用戶是否有權(quán)限創(chuàng)建此類資源赘来?
- GET
- 該用戶是否有權(quán)限查詢此類資源的權(quán)限现喳?
- 如果是查詢指定ID的資源,那么該用戶是否有查詢該資源的權(quán)限犬辰?
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)
- PUT
- 該用戶是否有更新該資源的權(quán)限嗦篱?
db_obj = self._get_db_obj(id) self._auth_check_action(context.session, db_obj.project_id, const.RBAC_PUT)
- 該用戶是否有更新該資源的權(quán)限嗦篱?
- DELETE
- 該用戶是否有刪除該資源的權(quán)限?
db_obj = self._get_db_obj(id) self._auth_check_action(context.session, db_obj.project_id, const.RBAC_DELETE)
- 該用戶是否有刪除該資源的權(quán)限?
其他注意點
- 查詢數(shù)據(jù)庫里的記錄時幌缝,為什么不指定租戶ID進行查詢灸促?
這樣可以實現(xiàn)超級管理員的功能(如果指定租戶ID進行查詢,那么“超級管理員”就查詢不到所有資源了)涵卵。 - Token中的租戶ID和URL中的租戶ID是否匹配浴栽,應(yīng)該在Controller初始化時就統(tǒng)一進行校驗,而不是每個Controller分別進行實現(xiàn)或調(diào)用轿偎,在Controller中進行的校驗主要是:資源的所屬的租戶ID與請求token(或url)中的租戶ID是否匹配以及RBAC吃度。