2015-08-18 34 views
5

我正在設計DRF應用程序的授權。我需要使用角色,而不僅僅是權限。設計Django Rest框架基於角色的授權

我有一個模型(例如project),其中我有一些可以被某些角色(例如admin)修改的信息(例如名稱,描述)。但同時還有其他角色(例如worker)不應該能夠修改該模型中的信息,但仍可以修改其他一些信息(例如初始日期和最終日期)。

我以爲這個問題有兩種解決方案。第一個是讀取發送的HTTP請求,並根據請求的內容定義要採取的操作。這意味着每次將新字段添加到模型時,我都必須修改此邏輯。這聽起來很難維護,容易出錯並且可能引入漏洞。

另一方面,我認爲我可以將模型分成兩個不同的模型。其中一個包含只有一個角色(admin)可修改的數據,另一個定義可由兩個角色(admin,worker)修改的其他數據。這樣,我就不必分析HTTP請求了,因爲如果我得到影響第一個模型的POST/PUT請求,並且用戶有一個工作者角色,我可以直接拒絕它。

這種情況發生在多個模型中。

我想知道是否有默認的方式去,或者如果我重新發明輪子。我認爲這種情況一定很常見。例如,我可以考慮一個git項目,在這個項目中,一些用戶可以在項目中做一件事,而不是其他人。

補充說明(意見將非常感激):

  • 我將最有可能使用django-role-permissions模塊來實現角色和權限。我無法使用django內置組,因爲雖然您可以爲它們添加權限,但我將使用它們對用戶進行分組(無需任何角色)。

  • 我將在權限文件中創建角色和權限(基於字符串的權限,如create_project,modify_project_description)之間的關係。

  • 當收到每個請求時,我將檢查哪些角色有權執行該操作並檢查用戶是否是這些角色中的任何角色(基於活動的授權,意味着在端點中我將檢查活動/操作的作用)。

回答

1

經過一番思考,我找到了兩個解決方案。

第一個解決方案(而不是像我在問題中提到的那樣劃分模型)爲每種必須發生的操作類型聲明不同的端點(URL)。然後在每個端點serializer中定義通過fields類變量的有效參數。

這意味着如果一個角色只能更新某些字段,我會爲此操作創建一個ModelViewSet,並在與此ModelViewSet相關的serializer類中只允許某些參數。

該解決方案存在很多問題,並且不是很RESTful。你可能會得到幾十個不同的URL。就我而言,鑑於API不大,行動有限,短期內可能不成問題,但確定在應用程序的要求發生變化時,它會成爲問題。

第二個(選擇)解決方案是確定您在其中定義那裏的行動已經發生(如果你以正確的方式構建了應用程序可以只是在ModelViewSet端點權限/角色表類名稱),要執行的動作(列表,檢索,創建...)可以交互的相關模型的字段以及可以與這些字段交互的角色。

我會建議使用字典作爲權限表使用的數據結構,因此每個權限檢查是O(1)

現在,每次您收到對該端點的請求時,都應該使用該表進行權限檢查。

我通過覆蓋ModelSetView類中的check_permissions()方法來實施權限檢查。小心並保持原有的check_permissions()功能。

2

聽起來就像你想要一些現場級別的安全。您可以考慮使用代理模型爲受限用戶提供有限的一組字段的寫訪問權限。

另一種選擇可能是使用自定義序列化程序類,它只對某些字段應用只讀。在ViewSet子類上的get_serializer可能是執行數據透視的好地方,您應該在self.request.user中找到當前用戶。

+1

你值得讚賞,因爲我最終實現了你提到的一切(除了代理模型)。 – newlog