1 權限控制是什么
認證(Authentication)和 授權(Authorization)是兩個概念:
-
認證的目的是為了認出用戶是誰,解決的是『Who am I』的問題;
-
而授權的目的是為了決定用戶能夠做什么,解決的是『What can I do』的問題。
形象的來說:假設系統是一個屋子,持有鑰匙的人可以開門進入屋子。那么屋子就是通過鎖和鑰匙來進行『認證』的,開門的過程對應的就是登陸。開門之后,能訪問哪個屋子,什么事情能做,什么事情不能做,就是『授權』的管轄范圍了。
某個主體(subject)對某個客體(object)需要實施某種操作(operation),系統對這種操作的限制就是權限控制。在一個安全的系統中,通過認證來確認主體的身份。客體是一種資源,是主體發起請求的對象。主體所能做什么,就是權限,權限可以細分為不同的能力,例如:在Linux文件系統中,將權限分為 讀、寫、執行 三種能力。"基於角色的訪問控制"和"基於數據的訪問控制"是進行系統安全設計時經常用到的兩種控制方式,下文會涉及到。
以下是一些常見的權限控制模型:
1.1 ACL
ACL(Access Control List) 控制訪問列表。在ACL中,包含用戶(User)、資源(Resource)、資源操作(Operation)三個關鍵要素。每一項資源,都配有一個列表,記錄哪些用戶可以對這項資源執行哪些操作。當系統試圖訪問這項資源時,會檢查這個列表中是否有關於當前用戶的操作權限。
總的來說,ACL是面向"資源"的訪問控制模型,機制是圍繞"資源"展開的。模型如下圖所示:
ACL典型的例子:
在 Linux 中,主體是系統用戶,客體是被訪問的文件,一個文件所能執行的操作分為讀(r)、寫(w)、執行(x),這三種操作同時對應着三種主體:文件擁有者、文件擁有者所在的用戶組、其他用戶。主體-客體-操作這三種的對應關系構成了 ACL 控制訪問列表,當用戶訪問文件時,能否成功將由 ACL 決定。
1.2 RBAC
1.2.1 名詞術語
用戶(user):人、機器、網絡等,進行資源或服務訪問的實施主體
角色(role):一個工作職能,被授予角色的用戶將具有相應的權威和責任
會話(session):從用戶到其激活的角色集合的一個映射
權限(permission):對受RBAC保護的一個或多個對象執行某個操作的許可
操作(operation):一個程序可執行的映像,被調用時為用戶執行某些功能
客體(object):需要進行訪問控制的系統資源,例如:文件、打印機、數據庫記錄等
1.2.2 RBAC定義
RBAC(Role-Based Access Control):基於角色的訪問控制。 RBAC認為授權實際就是 who,what,how 三者之間的關系,即 who 對 what 進行 how 的操作。
-
Who:權限的擁用者或主體(如 User、Group、Role 等等)
-
What:權限針對的對象或資源
-
How:具體的權限
RBAC的關注點在於 Role 和 User, Permission 的關系。稱為 User assignment(UA) 和 Permission assignment(PA)。關系的左右兩邊都是 Many-to-Many 關系。就是 user 可以有多個 role,role 可以包括多個 user。User 通過成為 Role 而得到這些 Role 的 Permission,Role 隔離了 User 和 Permission 的邏輯關系。
RBAC支持三個著名的安全原則:
-
最小權限原則:要求系統只授予主體必要的權限,而不要過度授權,這樣能有效減少系統、網絡、應用、數據庫出錯的機會。RBAC可以將其角色配置成其完成任務所需要的最小的權限集
-
責任分離原則:調用相互獨立互斥的角色來共同完成敏感的任務。例如:記賬員和財務管理員共同參與同一過賬
-
數據抽象原則:權限的抽象。如:財務操作用借款、存款等抽象權限,而不用操作系統提供的典型的讀、寫、執行權限。
1.2.3 RBAC分類
1.2.3.1 RBAC0
RBAC0:RBAC的核心部分,是通用的權限模型,其他的版本都是建立在 RBAC0 的基礎上並進行相應的擴展。 模型圖如下:

use和role關系:N:N
role和permission關系:N:N
在用戶的會話中保持激活狀態的角色的權限構成了用戶的可用權限
1.2.3.2 RBAC1
RBAC1:基於 RBAC0 的角色層次模型,角色層次定義了角色間的繼承關系,例如:角色 r1 繼承了角色 r2,r1 則擁有了 r2 的所有權限。模型圖如下:

使用第一種模型也可以,不過會存在數據冗余,沒有RBAC1更面向對象
1.2.3.3 RBAC2
RBAC2:基於 RBAC0 的約束模型,增加了職級分離關系,用來實施利益沖突策略防止組織中用戶的越權行為,限制了用戶的權限。包含SSD(靜態職級分離)和DSD(動態職級分離)概念。
SSD:用戶/角色分配約束,由2個參數定義 :
-
包含2或2個以上角色的角色集合
-
用戶擁有的角色在該角色集中小於某個閥值
DSD:會話與角色之間的約束,約束一個用戶會話可以激活的角色來限制用戶的權限。例如:一個用戶擁有3個角色,一個會話中只激活1個角色。模型圖如下

1.2.4 RBAC 接口
RBAC接口定義規范,可參考:GBT 25062-2010 信息安全技術 鑒別與授權 基於角色的訪問控制模型與管理規范
2 垂直權限(功能權限)
訪問控制是建立用戶與權限之間的關系,目前常用的一種方法就是基於 RBAC 模型,我們可稱之為『垂直權限』。例如:在一個論壇中,有admin、普通用戶、匿名用戶三種角色,admin有刪除、編輯、置頂帖子的權限,普通用戶有評論和瀏覽帖子的權限,匿名用戶只有瀏覽帖子的權限。目前已有 Shiro,Spring Security 等基於 RBAC 模型的成熟框架來處理功能權限管理和鑒權的問題。
垂直權限的漏洞舉例:Web應用程序在服務端沒有做權限控制,只是在前端菜單顯示上將部分頁面隱藏了。此時,惡意用戶可以猜測其他管理頁面的 URL,就可以訪問或控制其他角色擁有的數據或頁面,達到越權操作的目的,可能會使得普通用戶擁有了管理員的權限。
解決:對管理員所見的管理界面 URL,每次用戶訪問時,都要判定該用戶是否有訪問此 URL 的權限。推薦使用成熟的權限解決方案框架。
3 水平權限(數據權限)
用戶A和用戶B可能同屬於一個角色 RoleX,但用戶 A 和用戶 B 都各自有一些私有數據,正常情況下,用戶自己只能訪問自己的私有數據,例如:你有刪除郵件的功能(操作權限),但只能刪除自己的郵件,不能誤刪其他人的郵件(數據權限)。但在 RBAC 模型下,系統只會驗證用戶A是否屬於角色 RoleX,而不會判斷用戶A是否能訪問只屬於用戶B的數據 DataB,此時就可能發生越權訪問。
這種問題,稱之為『水平權限管理問題』,又可以稱之為『基於數據的訪問控制』:相比垂直權限管理來說,水平權限問題出現在同一個角色上,系統只驗證了能訪問數據的角色,沒有對數據的子集做細分,因此缺乏了一個用戶到數據級之間的對應關系。對於數據的訪問控制,與業務結合的比較緊密,目前還沒有統一的數據級權限管理框架,一般是具體問題具體解決。

數據權限就是控制訪問數據的可見范圍,表現形式是:當某用戶有操作權限時候,不代表對所有數據都有查看或管理的權限。一般表現為行權限和列權限:
-
行權限:限制用戶對某些行的訪問,例如:只能對某人、某部門的數據進行訪問;也可以是根據數據的范圍進行限制,例如:按合同額大小限制用戶對數據的訪問
-
列權限:限制用戶對某些列的訪問,例如:某些內容的摘要可以被查閱,但詳細內容只有 VIP 用戶能查閱
水平權限的漏洞案例:Web應用程序接受用戶的請求,修改某條數據id(資源的唯一編號)時,而沒有判斷當前用戶是否可以訪問該條記錄,導致惡意用戶可以修改本不屬於自己的數據。例如:`/api/v1/blog?blogId=xxx [DELETE]` 這是刪除博客內容的url,當用戶改變 blogId 時,后端如果未校驗博客的所屬人是否是當前用戶,則可以刪除其他人的博客內容。
解決方案:用戶做出相應動作時(新建、刪除、更新等)時,需要對其會話身份進行驗證(可采用Cookie機制),並且對用戶訪問的對象記錄校驗數據權限是否ok(按業務場景)。
4 OAuth
OAuth 是一個在不提供用戶名和密碼的情況下,授權第三方應用訪問 Web 資源的安全協議。例如一個 OAuth 場景:用戶將照片存儲在Google,然后在"雲沖印"的網站,將照片沖印出來。那么,"雲沖印"網站需要獲得用戶的授權來讀取Google上的用戶照片。
OAuth 的一些名詞:
-
Third-party application:第三方應用程序,又稱 "Client" 客戶端,上例中的"雲沖印"網站
-
HTTP Service:HTTP服務提供商,上例中的Google
-
Resource Owner:資源所有者,就是用戶
-
User Agent:用戶代理,就是瀏覽器
-
Authorization server:認證服務器,即服務商提供商專門處理認證的服務器
-
Resource server:資源服務器,即服務提供商存放用戶生成的資源的服務器
OAuth 的授權流程:

A:用戶打開第三方應用程序 Client,Client 要求用戶給與授權
B:用戶同意給予 Client 授權
C:Client 使用 B 步驟中獲得的授權,向認證服務器申請令牌
D:認證服務器對 Client 進行認證之后,確認無誤,同意發放令牌
E:Client 使用令牌,向資源服務器申請獲取資源
F:資源服務器確認令牌無誤之后,同意向 Client 開放資源
對於 B 步驟中的用戶給 Client 第三方程序授權,OAuth2.0 定義了以下四種授權模式:
4.1 授權碼模式(authorization code)
授權碼模式是功能最完整、流程最嚴密的授權模式,它的特點是通過 Client 的后台服務器,與服務提供商的認證服務器進行交互

將每一步驟與所需的參數用時序圖表示如下:

其中A.3中的scope是申請用戶授權的權限范圍,會向用戶顯示一個可授權列表,例如:獲取用戶信息、相冊列表、點贊等資源,例如下圖所示:

實例可參考:微信公眾平台技術文檔-微信網頁授權
QQ互聯-使用Authorization_Code獲取Access_Token
4.2 簡化模式(implicit)
簡化模式不通過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了授權碼的步驟。所有步驟都在瀏覽器中完成,令牌對訪問者是可見的,且 Client 不需要認證

將每一步驟與所需的參數用時序圖表示如下:

實例可參考:QQ互聯-使用Implicit_Grant方式獲取Access_Token
4.3 密碼模式(resource owner password credentials)
密碼模式中,用戶向 Client 提供自己的用戶名和密碼,Client 使用這些信息,向服務提供商索要權限。這種模式中,用戶需要將自己的密碼提供給 Client,但 Client 處不得存儲密碼,這通常用於用戶對 Client 高度信任的情況下,例如:Client 是操作系統的一部分或一個著名公司。而認證服務器只有在其他授權模式無法執行情況下,才會采用這種模式。

將每一步驟與所需的參數用時序圖表示如下:

4.4 客戶端模式(client credentials)
客戶端模式,指 Client 以自己的名義,而不是以用戶的名義,向服務提供商進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,用戶直接向 Client 注冊,Client 以自己的名義要求服務提供商提供服務,其實不存在用戶的授權問題。

將每一步驟與所需的參數用時序圖表示如下:

