這兩天工做中又用到了Auth2.0協議,發現以前看的已經忘了差很少了。因此想寫篇BLOG記下,加深下印象
根據RFC6749協議介紹,Auth2.0是一個受權(官方用的是authorization,這裏要注意受權authorization和認證authentication的區別)協議,它容許第三方應用經過Http Service來獲取部分權限。api
RFC6749協議給出的受權流程圖以下:瀏覽器
+--------+ +---------------+ | |--(A)- Authorization Request ->| Resource | | | | Owner | | |<-(B)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(C)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(D)----- Access Token -------| | | | +---------------+ | | | | +---------------+ | |--(E)----- Access Token ------>| Resource | | | | Server | | |<-(F)--- Protected Resource ---| | +--------+ +---------------+ Figure 1: Abstract Protocol Flow
A. 第三方應用發起受權
B. 平臺方彈出受權頁面,頁面顯示受權範圍
C. 用戶贊成受權,而後第三方應用去獲取access_token
D. 平臺方返回access_token
E. 而後第三方應用拿獲取到的access_token去調用平臺方api
F. 平臺方返回資源app
auth2.0有4中受權方式
Authorization Code方式是用的最多的一種方式,流程以下:編碼
+----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI ---->| | | User- | | Authorization | | Agent -+----(B)-- User authenticates --->| Server | | | | | | -+----(C)-- Authorization Code ---<| | +-|----|---+ +---------------+ | | ^ v (A) (C) | | | | | | ^ v | | +---------+ | | | |>---(D)-- Authorization Code ---------' | | Client | & Redirection URI | | | | | |<---(E)----- Access Token -------------------' +---------+ (w/ Optional Refresh Token)
A. 第三方應用發起受權
B. 用戶贊成受權
C. 平臺方重定向到事先約定好的URL,並在URL裏附加上code參數
D. 第三方應用解析URL並作參數校驗後,用code和在平臺方生成的key和secret去換access_token
E. 平臺方作校驗後放回access_token
F. 第三方應用用拿到的access_token去獲取用戶受權的數據url
與簡化模式(Implicit)不一樣的是,Authorization Code獲取access_token是在第三方應用的Server上進行的,所以access_token並不會暴露給瀏覽器或者客戶端code
簡化模式(Implicit)是受權碼模式(Authorization Code)的簡化版,是給用瀏覽器做爲客戶端的應用用的,流程圖以下orm
+----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI --->| | | User- | | Authorization | | Agent -|----(B)-- User authenticates -->| Server | | | | | | |<---(C)--- Redirection URI ----<| | | | with Access Token +---------------+ | | in Fragment | | +---------------+ | |----(D)--- Redirection URI ---->| Web-Hosted | | | without Fragment | Client | | | | Resource | | (F) |<---(E)------- Script ---------<| | | | +---------------+ +-|--------+ | | (A) (G) Access Token | | ^ v +---------+ | | | Client | | | +---------+
密碼模式是將用戶在平臺上的帳戶密碼提供給第三方應用,好比各類搶火車票的軟件用的這種模式。這種認證模式的缺點顯而易見。csrf
客戶端模式指客戶端以本身的名義,向"服務提供商"進行認證blog
Authorization Request的參數是以 application/x-www-form-urlencoded方式寫到URL上的
response_type: 值必須設置爲code,token或者其餘約定的值
client_id: 平臺方分給應用方的Id
redirect_uri(可選): 回調url,redirect_uri必須作嚴格限制,以Github爲例token
CALLBACK: http://example.com/path
GOOD: http://example.com/path
GOOD: http://example.com/path/subdi...
BAD: http://example.com/bar
BAD: http://example.com/
BAD: http://example.com:8080/path
BAD: http://oauth.example.com:8080/path
BAD: http://example.org
scope: 應用方申請的權限範圍,這個是由平臺方定義的
state: state的值建議設置爲不可猜想的,其目的是防止csrf攻擊
code: 平臺方傳給應用方的code,應用方的在請求access_token的是有用到。code只能用一次。並且當code被使用屢次的時候,平臺方應當拒絕請求,而且回收全部已經分配的access_token(文檔建議這麼作,但實際上沒見到有平臺作這麼嚴格)
做爲平臺方,code應當和client_id是對應的,是爲了防止攻擊者截取回調請求,並將code替換爲事先準備好的code,從而誘導用戶綁定攻擊者本身的應用,從而竊取用戶信息
state: 應用方傳給平臺方的state參數,平臺方回回傳給應用方。state是用來防止csrf攻擊的,所以它的值是應該通過編碼的,
refresh_token: refresh_token是可選的,當access_token過時時,能夠用refresh_token去獲取新的access_token
官方文檔,注意文檔中MUST
和SHOULD
,NOTE
等字眼,這裏面寫着最佳實踐和一些所謂的坑
知道創宇的一篇關於OAuth漏洞的分析與防範建議