1.什么是OAuth
OAuth 是一個開放標準,允許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應用。目前,OAuth 的最新版本為 2.0
OAuth 允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的網站(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth 允許用戶授權第三方網站訪問他們存儲在另外的服務提供者上的信息,而不需要分享他們的訪問許可或他們數據的所有內容。
OAuth 2.0 的核心概念
OAuth 2.0 主要有4類角色:
resource owner:資源所有者,指終端的“用戶”(user)。
resource server:資源服務器,即服務提供商存放受保護資源。訪問這些資源,需要獲得訪問令牌(access token)。它與認證服務器,可以是同一臺服務器,也可以是不同的服務器。如果,我們訪問新浪博客網站,那么如果使用新浪博客的賬號來登錄新浪博客網站,那么新浪博客的資源和新浪博客的認證都是同一家,可以認為是同一個服務器。如果,我們是新浪博客賬號去登錄了知乎,那么顯然知乎的資源和新浪的認證不是一個服務器。
client:客戶端,代表向受保護資源進行資源請求的第三方應用程序。
authorization server: 授權服務器, 在驗證資源所有者并獲得授權成功后,將發(fā)放訪問令牌給客戶端。
3.OAuth 2.0 的認證流程

(A)用戶打開客戶端以后,客戶端請求資源所有者(用戶)的授權。
(B)用戶同意給予客戶端授權。
(C)客戶端使用上一步獲得的授權,向認證服務器申請訪問令牌。
(D)認證服務器對客戶端進行認證以后,確認無誤,同意發(fā)放訪問令牌。
(E)客戶端使用訪問令牌,向資源服務器申請獲取資源。
(F)資源服務器確認令牌無誤,同意向客戶端開放資源。

其中,用戶授權有四種模式:
授權碼模式(authorization code)
簡化模式(implicit)
密碼模式(resource owner password credentials)
客戶端模式(client credentials)
3.1授權碼模式(authorization code): Web-server、apps

3.1.1 為何引入authorization_code?
協(xié)議設計中,為什么要使用authorization_code來交換access_token?這是讀者容易想到的一個問題。也就是說,在協(xié)議的第3步,為什么不直接將access_token通過重定向方式返回給Client呢?
如果直接返回access_token,協(xié)議將變得更加簡潔,而且少一次Client與AS之間的交互,性能也更優(yōu)。那為何不這么設計呢?協(xié)議文檔[1]中并沒有給出這樣設計的理由,但也不難分析:
(1) 瀏覽器的redirect_uri是一個不安全信道,此方式不適合于傳遞敏感數據(如access_token)。因為uri可能通過HTTP referrer被傳遞給其它惡意站點,也可能存在于瀏覽器cacher或log文件中,這就給攻擊者盜取access_token帶來了很多機會。另外,此協(xié)議也不應該假設RO用戶代理的行為是可信賴的,因為RO的瀏覽器可能早已被攻擊者植入了跨站腳本用來監(jiān)聽access_token。因此,access_token通過RO的用戶代理傳遞給Client,會顯著擴大access_token被泄露的風險。 但authorization_code可以通過redirect_uri方式來傳遞,是因為authorization_code并不像access_token一樣敏感。即使authorization_code被泄露,攻擊者也無法直接拿到access_token,因為拿authorization_code去交換access_token是需要驗證Client的真實身份。也就是說,除了Client之外,其他人拿authorization_code是沒有用的。 此外,access_token應該只頒發(fā)給Client使用,其他任何主體(包括RO)都不應該獲取access_token。協(xié)議的設計應能保證Client是唯一有能力獲取access_token的主體。引入authorization_code之后,便可以保證Client是access_token的唯一持有人。當然,Client也是唯一的有義務需要保護access_token不被泄露。
(2) 引入authorization_code還會帶來如下的好處。由于協(xié)議需要驗證Client的身份,如果不引入authorization_code,這個Client的身份認證只能通過第1步的redirect_uri來傳遞。同樣由于redirect_uri是一個不安全信道,這就額外要求Client必須使用數字簽名技術來進行身份認證,而不能用簡單的密碼或口令認證方式。引入authorization_code之后,AS可以直接對Client進行身份認證(見步驟4和5),而且可以支持任意的Client認證方式(比如,簡單地直接將Client端密鑰發(fā)送給AS)。
3.2implicit(簡單模式): Browser-based apps,Mobile apps

4. 基于Web安全的考慮
OAuth協(xié)議設計不同于簡單的網絡安全協(xié)議的設計,因為OAuth需要考慮各種Web攻擊,比如CSRF (Cross-Site Request Forgery), XSS (Cross Site Script), Clickjacking。要理解這些攻擊原理,讀者需要對瀏覽器安全(eg, Same Origin Policy, 同源策略)有基本理解。比如,在redirect_uri中引入state參數就是從瀏覽器安全角度考慮的,有了它就可以抵制CSRF攻擊。如果沒有這個參數,攻擊者便可以在redirect_uri中注入攻擊者提供的authorization_code或access_token,結果可能導致Client訪問錯誤的資源(比如,將款項匯到一個錯誤的帳號)。
5.參考鏈接
OAuth 2.0 認證的原理與實踐
OAuth2.0實戰(zhàn)1(分析簡書的微信登陸及實現(xiàn))
OAuth 授權的工作原理是怎樣的?足夠安全嗎?
幫你深入理解OAuth2.0協(xié)議
Oauth2.0原理