認證(Authentication)和 受權(Authorization)是兩個概念:html
認證的目的是爲了認出用戶是誰,解決的是『Who am I』的問題;前端
而受權的目的是爲了決定用戶可以作什麼,解決的是『What can I do』的問題。git
形象的來講:假設系統是一個屋子,持有鑰匙的人能夠開門進入屋子。那麼屋子就是經過鎖和鑰匙來進行『認證』的,開門的過程對應的就是登錄。開門以後,能訪問哪一個屋子,什麼事情能作,什麼事情不能作,就是『受權』的管轄範圍了。github
某個主體(subject)對某個客體(object)須要實施某種操做(operation),系統對這種操做的限制就是權限控制。在一個安全的系統中,經過認證來確認主體的身份。客體是一種資源,是主體發起請求的對象。主體所能作什麼,就是權限,權限能夠細分爲不一樣的能力,例如:在Linux文件系統中,將權限分爲 讀、寫、執行 三種能力。"基於角色的訪問控制"和"基於數據的訪問控制"是進行系統安全設計時常常用到的兩種控制方式,下文會涉及到。數據庫
如下是一些常見的權限控制模型: 後端
ACL(Access Control List) 控制訪問列表。在ACL中,包含用戶(User)、資源(Resource)、資源操做(Operation)三個關鍵要素。每一項資源,都配有一個列表,記錄哪些用戶能夠對這項資源執行哪些操做。當系統試圖訪問這項資源時,會檢查這個列表中是否有關於當前用戶的操做權限。api
總的來講,ACL是面向"資源"的訪問控制模型,機制是圍繞"資源"展開的。模型以下圖所示:瀏覽器
ACL典型的例子:安全
在 Linux 中,主體是系統用戶,客體是被訪問的文件,一個文件所能執行的操做分爲讀(r)、寫(w)、執行(x),這三種操做同時對應着三種主體:文件擁有者、文件擁有者所在的用戶組、其餘用戶。主體-客體-操做這三種的對應關係構成了 ACL 控制訪問列表,當用戶訪問文件時,可否成功將由 ACL 決定。 服務器
用戶(user):人、機器、網絡等,進行資源或服務訪問的實施主體
角色(role):一個工做職能,被授予角色的用戶將具備相應的權威和責任
會話(session):從用戶到其激活的角色集合的一個映射
權限(permission):對受RBAC保護的一個或多個對象執行某個操做的許可
操做(operation):一個程序可執行的映像,被調用時爲用戶執行某些功能
客體(object):須要進行訪問控制的系統資源,例如:文件、打印機、數據庫記錄等
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能夠將其角色配置成其完成任務所須要的最小的權限集
責任分離原則:調用相互獨立互斥的角色來共同完成敏感的任務。例如:記帳員和財務管理員共同參與同一過帳
數據抽象原則:權限的抽象。如:財務操做用借款、存款等抽象權限,而不用操做系統提供的典型的讀、寫、執行權限。
RBAC0:RBAC的核心部分,是通用的權限模型,其餘的版本都是創建在 RBAC0 的基礎上並進行相應的擴展。 模型圖以下:
use和role關係:N:N
role和permission關係:N:N
在用戶的會話中保持激活狀態的角色的權限構成了用戶的可用權限
RBAC1:基於 RBAC0 的角色層次模型,角色層次定義了角色間的繼承關係,例如:角色 r1 繼承了角色 r2,r1 則擁有了 r2 的全部權限。模型圖以下:
使用第一種模型也能夠,不過會存在數據冗餘,沒有RBAC1更面向對象
RBAC2:基於 RBAC0 的約束模型,增長了職級分離關係,用來實施利益衝突策略防止組織中用戶的越權行爲,限制了用戶的權限。包含SSD(靜態職級分離)和DSD(動態職級分離)概念。
SSD:用戶/角色分配約束,由2個參數定義 :
包含2或2個以上角色的角色集合
用戶擁有的角色在該角色集中小於某個閥值
DSD:會話與角色之間的約束,約束一個用戶會話能夠激活的角色來限制用戶的權限。例如:一個用戶擁有3個角色,一個會話中只激活1個角色。模型圖以下
RBAC接口定義規範,可參考:GBT 25062-2010 信息安全技術 鑑別與受權 基於角色的訪問控制模型與管理規範
訪問控制是創建用戶與權限之間的關係,目前經常使用的一種方法就是基於 RBAC 模型,咱們可稱之爲『垂直權限』。例如:在一個論壇中,有admin、普通用戶、匿名用戶三種角色,admin有刪除、編輯、置頂帖子的權限,普通用戶有評論和瀏覽帖子的權限,匿名用戶只有瀏覽帖子的權限。目前已有 Shiro,Spring Security 等基於 RBAC 模型的成熟框架來處理功能權限管理和鑑權的問題。
垂直權限的漏洞舉例:Web應用程序在服務端沒有作權限控制,只是在前端菜單顯示上將部分頁面隱藏了。此時,惡意用戶能夠猜想其餘管理頁面的 URL,就能夠訪問或控制其餘角色擁有的數據或頁面,達到越權操做的目的,可能會使得普通用戶擁有了管理員的權限。
解決:對管理員所見的管理界面 URL,每次用戶訪問時,都要斷定該用戶是否有訪問此 URL 的權限。推薦使用成熟的權限解決方案框架。
用戶A和用戶B可能同屬於一個角色 RoleX,但用戶 A 和用戶 B 都各自有一些私有數據,正常狀況下,用戶本身只能訪問本身的私有數據,例如:你有刪除郵件的功能(操做權限),但只能刪除本身的郵件,不能誤刪其餘人的郵件(數據權限)。但在 RBAC 模型下,系統只會驗證用戶A是否屬於角色 RoleX,而不會判斷用戶A是否能訪問只屬於用戶B的數據 DataB,此時就可能發生越權訪問。
這種問題,稱之爲『水平權限管理問題』,又能夠稱之爲『基於數據的訪問控制』:相比垂直權限管理來講,水平權限問題出如今同一個角色上,系統只驗證了能訪問數據的角色,沒有對數據的子集作細分,所以缺少了一個用戶到數據級之間的對應關係。對於數據的訪問控制,與業務結合的比較緊密,目前尚未統一的數據級權限管理框架,通常是具體問題具體解決。
數據權限就是控制訪問數據的可見範圍,表現形式是:當某用戶有操做權限時候,不表明對全部數據都有查看或管理的權限。通常表現爲行權限和列權限:
行權限:限制用戶對某些行的訪問,例如:只能對某人、某部門的數據進行訪問;也能夠是根據數據的範圍進行限制,例如:按合同額大小限制用戶對數據的訪問
列權限:限制用戶對某些列的訪問,例如:某些內容的摘要能夠被查閱,但詳細內容只有 VIP 用戶能查閱
水平權限的漏洞案例:Web應用程序接受用戶的請求,修改某條數據id(資源的惟一編號)時,而沒有判斷當前用戶是否能夠訪問該條記錄,致使惡意用戶能夠修改本不屬於本身的數據。例如:`/api/v1/blog?blogId=xxx [DELETE]` 這是刪除博客內容的url,當用戶改變 blogId 時,後端若是未校驗博客的所屬人是不是當前用戶,則能夠刪除其餘人的博客內容。
解決方案:用戶作出相應動做時(新建、刪除、更新等)時,須要對其會話身份進行驗證(可採用Cookie機制),而且對用戶訪問的對象記錄校驗數據權限是否ok(按業務場景)。
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 定義瞭如下四種受權模式:
受權碼模式是功能最完整、流程最嚴密的受權模式,它的特色是經過 Client 的後臺服務器,與服務提供商的認證服務器進行交互
將每一步驟與所需的參數用時序圖表示以下:
其中A.3中的scope是申請用戶受權的權限範圍,會向用戶顯示一個可受權列表,例如:獲取用戶信息、相冊列表、點贊等資源,例以下圖所示:
實例可參考:微信公衆平臺技術文檔-微信網頁受權
QQ互聯-使用Authorization_Code獲取Access_Token
簡化模式不經過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了受權碼的步驟。全部步驟都在瀏覽器中完成,令牌對訪問者是可見的,且 Client 不須要認證
將每一步驟與所需的參數用時序圖表示以下:
實例可參考:QQ互聯-使用Implicit_Grant方式獲取Access_Token
密碼模式中,用戶向 Client 提供本身的用戶名和密碼,Client 使用這些信息,向服務提供商索要權限。這種模式中,用戶須要將本身的密碼提供給 Client,但 Client 處不得存儲密碼,這一般用於用戶對 Client 高度信任的狀況下,例如:Client 是操做系統的一部分或一個著名公司。而認證服務器只有在其餘受權模式沒法執行狀況下,纔會採用這種模式。
將每一步驟與所需的參數用時序圖表示以下:
客戶端模式,指 Client 以本身的名義,而不是以用戶的名義,向服務提供商進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,用戶直接向 Client 註冊,Client 以本身的名義要求服務提供商提供服務,其實不存在用戶的受權問題。
將每一步驟與所需的參數用時序圖表示以下: