在程式複雜程度不斷上公升的過程中,無可避免需要觸碰到許可權控制,而許可權控制又與業務邏輯緊緊相關,市場上出現了大量的許可權控制產品,而程式的開發,講究去繁化簡的抽象,在我的開發過程中,逐漸發現程式的許可權控制核心不外乎兩個方面:1、資源定位;2、訪問控制列表。本文主要針對資源定位進行分析,並解決一些我所遇見過的問題。而在mvc上,mvc提供給我們了非常好的訪問控制擴充套件機制,我們能夠通過這些機制更好地控制系統許可權。
在我們之前的開發中,針對asp.net下webform進行開發,很多人都採用了繼承page基類自定義basepage,構造自己的驗證邏輯後再將最終的展示頁面繼承於basepage,所有的驗證邏輯中,也必須解決我上文中提到的兩個問題:資源定位和訪問控制列表。而webform下使用路由機制的機會並不多,意義也並不大,在這個背景下,大多數人產生了這樣的錯覺:使用url進行資源定位就夠了。我所見過的幾個專案,大多採用了這個辦法,或者這個辦法的細微變種。而webform的機制也決定了這個方法是具有一定可行性的,每乙個資源(頁面)都是乙個類,資源定位較為容易。而進入mvc時代後,一切都發生了改變。在mvc的場景下,你將遇到以下幾個問題:
1、 路由機制的引入會出現乙個資源多個url的可能以及增加area等引數後url的不確定性。
2、 action過載的問題難以解決。例如乙個頁面order,在get方法下不帶參訪問是被允許的,而在post下帶參訪問是被禁止的,但這兩個資源的url都是 /order/,在一些第三方庫的輔助下,甚至能有更多的過載action,這就導致url定位機制的全面失效。
而面對上述情況,用一種什麼樣的方式進行資源的定位、控制就成為放在我們面前的難題。在mvc下,可以認為每乙個方法(action)即為乙個資源(頁面),用何種方法能在程式外部控制這些資源使得許可權控制能對其輕鬆進行,這是整個問題的核心。上文說到,每個方法即為乙個資源,那我們是否可以將方法名、方法簽名作為資源的定位標識?答案是可以的。
在mvc下,進行許可權控制,很自然地想到了使用自定義authorizationfilter來進行控制,那麼在這個attribute中是可以獲得方法相關資訊的。
var t =(reflectedactiondescriptor) filtercontext.actiondescriptor;var method= t.methodinfo.tostring();
在派生自filterattribute, iauthorizationfilter的自定義attribute中,可以根據上面兩個方法獲取方法的完整簽名,包括返回型別、方法名、引數型別。
通過這個方法是可以進行許可權控制的,但是這個方法存在著乙個致命的缺點:返回值的型別名、引數的型別名,有的是完全限定名,即需要帶命名空間,而有的是不完全限定名。而這個完全限定名的獲取是較為繁瑣的,因此,這個方法的可操作性大大降低。
那如何優雅地定位到我們所需要控制的資源呢?我們是否可以為我們所需要的資源取乙個名字,然後在訪問控制列表中將這個名字新增進去,每次執行這個action的時候獲取當前action的名字,然後在訪問控制列表中進行比對就可以解決這個問題。那如何將資源進行命名就成了解決問題的關鍵。**級的資源控制必須想到元資料,而需要在元資料中增加資訊,這個任務自然又落到attribute的身上。
我們自定義乙個attribute為action標註資源名稱:
[attributeusage(attributetargets.method, allowmultiple = false, inherited = false)]
public
sealed
class
resourcecustomernameattribute : attribute
public
string
resourcename
}}
這個attribute實現的功能很簡單:為資源進行命名(如果方便,使用id會更高效一點)。
完成了對資源的命名,接下來需要對資源與訪問控制列表進行比對,我是這樣使用的:繼承filterattribute, iauthorizationfilter,在派生類中先獲取resourcecustomernameattribute例項
然後用attribute.resourcename屬性與我們的訪問控制列表進行比對:
publicvoid
onauthorization(authorizationcontext filtercontext)
if (acl == null || !acl.any())
));}
else
else
)); }
}}
如果比對成功則獲取相應訪問許可,可以對資源進行訪問,若比對失敗則跳轉至授權失敗頁面。
而在實際的使用過程中,我們在登入成功後,將構造使用者的acl,並將acl存入session中,之後使用者在每一次的訪問中均使用session中的acl進行比對,授權。
在這個具體實現中,我有乙個難以處理的問題:即使用者訪問頁面時若未授權,則跳轉到未授權提示頁面,若使用者進行基於json傳遞的ajax呼叫時如何向使用者提供合適的資訊?之前考慮過使用contenttype來判斷,可是後來覺得這會導致開發之中的約定過多(更何況我對很多人對http協議的了解程度並不抱有信心)。不知各位是否有更好的辦法來實現多種錯誤返回資訊?望不吝賜教。
模組的具體**已託管於github:
功能核心模組已經上傳,示例正被gfw狂虐~各位稍安勿躁,如有靠譜的全域性科學上網方法的同學也希望悄悄告訴我一下~t.t
歡迎參考,提出您的寶貴意見。
基於角色的許可權控制
asp forums中基於角色的許可權控制 asp.頁面如何控制頁面依據不同使用者許可權有不可見 可見 編輯 三種操作許可權 做過許可權管理和想做許可權管理的人進來 附我的思路 懇求許可權分配的例子 高分求使用者許可權管理 c 或演算法 請問在 artclient應用中,如何做到科學的身份驗證和許可...
基於角色的許可權控制
aspnetforums中基於角色的許可權控制 asp.net頁面如何控制頁面依據不同使用者許可權有不可見 可見 編輯 三種操作許可權 做過許可權管理和想做許可權管理的人進來 附我的思路 懇求許可權分配的例子 高分求使用者許可權管理 c 或演算法 請問在smartclient應用中,如何做到科學的身...
PBAC基於策略的許可權控制
在pb實現一般管理系統的時候,我們會遇到這樣一種情況,作為乙個系統,可以分為若干個子系統,有多個操作員對它進行操作,每個操作員對各個子系統的許可權不同,甚至在同一子系統中,操作員對各個選單項的操作許可權也不一樣,更細一點,不同的操作員對於同一視窗中某一按鈕的操作許可權也是不一樣的,那麼,怎樣較好地實...