本文討論瞭如何使用角色的概念來管理安全策略,以及基於角色的安全應用程式安全機制在很大程度上是不夠的。我討論了我認為是保護應用程式更好的方法。
什麼是角色?
當談到應用程式安全性時,大多數人都對現有的角色概念感到滿意。角色是通常代表一組行為或責任的命名實體。這些行為轉化為你可以或不可以用軟體應用程式做的事情。 角色通常分配給使用者帳戶,因此通過關聯,使用者可以“完成”歸因於各種角色的事情。
例如,如果使用者登入到應用程式,並且他們的帳戶被分配了“專案經理”角色,那麼我們就開始臆測該使用者可以“做”專案經理在應用程式中能夠做的所有事情——在專案中新增或刪除員工,生成專案報告等。
在這個意義上,角色主要是一個行為概念:角色給你一個使用者可以在應用程式中做什麼的概念。
RBAC
一個角色主要是一個行為概念,開發軟體的邏輯步驟是使用角色作為控制訪問應用程式功能或資料的手段。 正如您所預料的那樣,大多數人稱之為基於角色的訪問控制(簡稱“RBAC”)。 但是,實際實現和執行訪問控制主要有兩種方式:一種是隱式的,另一種是顯式的。 目前絕大多數的軟體應用程式都使用隱式訪問控制。 我認為顯式訪問控制對於保護當今的軟體應用程式來說更好。
Implicit Access Control 如前所述,角色代表行為或責任。但是,我們如何確切地知道什麼樣的行為或責任與角色相關?
答案是,對於絕大多數的應用程式,你不知道這個角色代表什麼。您當然有一個好主意 - 您知道具有“管理員”角色的人可能會鎖定使用者帳戶或配置應用程式的某些部分,也可能是分配了“客戶”角色的使用者帳戶可以將商品放入購物車或請求新產品。但通常沒有什麼具體定義這些行為是什麼。
以字串“Project Manager”為例。 這只是一個字串名稱——除此之外,軟體程式可以檢視“基於這個名稱,我知道使用者分配這個角色可以做X,Y和Z”。 開發人員通常使用這個名字來編寫應用程式。 例如,要檢視使用者是否被允許檢視專案報告,通常會看到如下所示的程式碼:
//Listing 1. Example Implicit Role-Based Access Control security check:
if (user.hasRole("Project Manager") ) {
//show the project report button
} else {
//don't show the button
}
複製程式碼
在此示例程式碼塊中,軟體開發人員根據“專案經理”角色(可能是專案要求)做出是否顯示按鈕的決定。但是請注意,上面的程式碼中沒有任何明確的說“專案經理角色被允許檢視專案報告”。沒有人在軟體中的任何地方定義行為陳述——這意味著“專案經理”使用者可以檢視專案報告,因此開發人員編寫反映該假設的if/else語句。
脆弱的安全政策
像上面的例子那樣的安全訪問控制非常脆弱。也就是說,即使安全要求發生輕微變化,也很可能會破壞,失敗或導致效率低下。 舉例來說,讓我們假設編寫軟體的團隊被告知:“順便說一下,我們需要一個新的 部門經理 角色,他們也需要能夠檢視專案報告。實現它”。 現在軟體開發人員需要回到程式碼中來改變它是這樣的:
//Listing 2. Example Modified Implicit Role-Based Access Control security check:
if (user.hasRole("Project Manager") || user.hasRole("Department Manager") ) {
//show the project report button
} else {
//don't show the button
}
複製程式碼
然後,開發人員需要更新測試用例,重新構建軟體,檢查存在的任何質量保證流程,以及安排重新部署到生產環境——所有這些都是由於新的安全要求。 但是,如果管理層回來並要求另一個角色能夠檢視報告,會發生什麼?或者如果他們以後需要移除那個能力呢? 或者,如果軟體需要支援在執行時動態建立或刪除角色的功能,那麼他們希望客戶能夠自己配置角色呢? 在任何這些情況下,常見的隱式(靜態字串)基於角色的訪問控制方法都無法滿足安全需求。作為一個理想的安全策略,在發生變化時是無需做出原始碼級別的調整的。
一種更好的方式
正如我們上面看到的,用隱式訪問控制方法改變安全策略可能會對軟體開發產生影響。如果安全策略更改沒有強制程式碼重構,那將會好很多。理想情況下,如果安全策略可以在應用程式執行時進行更改,那麼最好不要影響終端使用者。這對於安全來說甚至更好,因為如果您發現錯誤或危險(或者您犯了策略錯誤),則可以將策略快速更改為正確的配置,並且軟體仍然可以正常執行。
從根本上說,這些檢查試圖保護資源(專案報告)以及使用者可以對這些資源做什麼操作(例如檢視/閱讀這些資源)。當你把它分解到這個最原始的層次時,你就可以開始用更細粒度(和變化彈性)的方式來描述安全策略了。
//Listing 3. Example Explicit Access Control security check:
if (user.isPermitted("projectReport:view:12345")) {
//show the project report button
} else {
//don't show the button
}
複製程式碼
這個例子更明確的是什麼訪問被控制。冒號分隔的語法在這裡並不重要——這僅僅是一個例子。更重要的是,我們基本上是檢查“如果當前使用者可以檢視ID為”12345“的”projectReport“,則顯示”專案報告按鈕“。也就是說,我們用一個使用者帳戶明確地歸納了關於特定資源例項的具體行為陳述。
什麼是好的方式?
-
減少程式碼重構:通過基於應用程式能做什麼的程式碼,我們將安全性基於應用程式本身核心的東西,以及應用程式與之互動的資源變化要少得多。使用這種方法,軟體開發人員可以修改安全檢查,因為他們在應用程式的功能上工作 - 而不是像隱式RBAC經常需要的那樣。
-
資源和行動是直觀的:代表什麼被保護,以及如何採取行動是一個更自然的思考問題的方式。物件導向的程式設計範例和REST通訊模型從根本上反映了這個觀點,並因此而非常成功。
-
靈活的安全模型:上面的程式碼示例並不指定如何允許使用者,組或角色對資源執行操作。這意味著可以支援任何安全模型設計。例如,也許行為(許可權)可以直接分配給使用者。或者也許他們可以被分配給一個角色,而角色又被分配給一個使用者。也許有團體的概念,與角色等有聯絡。可能性是開放的,可以根據您的應用程式進行定製。
-
外部化安全策略管理:由於原始碼只反映資源和行為,而不反映使用者,組和角色的組合,所以這種關聯管理可以外部化到程式碼的不同部分或專用工具或管理控制檯。這意味著開發人員不需要花時間進行安全策略更改,相反,業務分析師甚至終端使用者可以根據需要更改安全策略。
歡迎關注:www.renrunyun.com