文/趙龍 李秀紅 馬玉爽
OAuth 2.0讓統(tǒng)一身份認(rèn)證更安全
文/趙龍 李秀紅 馬玉爽
如今,越來越多的Web應(yīng)用和App應(yīng)用都涉及到用戶的參與,用戶的統(tǒng)一身份認(rèn)證和數(shù)據(jù)權(quán)限安全問題愈加嚴(yán)重,利用穩(wěn)定的Web架構(gòu)和認(rèn)證機(jī)制,才能保障數(shù)據(jù)安全。
目前常見的身份認(rèn)證方法有基于秘密信息的身份認(rèn)證方法和基于物理安全性的身份認(rèn)證方法,而基于秘密信息中的口令核對應(yīng)用最廣泛,OAuth協(xié)議是目前比較流行的基于口令核對的用戶驗(yàn)證與授權(quán)協(xié)議。Django是Python的一個開源Web開發(fā)框架.REST(Representational State Transfer,表述性狀態(tài)轉(zhuǎn)移)是當(dāng)前Web體系結(jié)構(gòu)的一種架構(gòu)風(fēng)格。
REST與Django REST framework服務(wù)
REST(Representational State Transfer),即“表述性狀態(tài)轉(zhuǎn)移”,由Roy Thomas Fielding博士在2000年的博士論文中首次提出。REST將需要操作的事物抽象為資源,同時給每一個資源賦予唯一的資源標(biāo)識符URI,并通過HTTP處理和傳輸資源狀態(tài)。
Restful Web服務(wù)也叫Restful Web API,是符合Rest風(fēng)格的輕量級Web服務(wù),其主要特點(diǎn)有所有資源都有唯一URI作為識別符、使用標(biāo)準(zhǔn)方法、資源多重表述、無狀態(tài)通信。通過 HTTP協(xié)議中定義的方法(POST,GET,PUT,DELETE)對資源進(jìn)行CRUD(Create, Retrieve, Update, Delete)操作。
Django REST framework是基于Django這個Web框架的REST模塊,主要提供了資源的API操作,封裝各種對數(shù)據(jù)資源的操作,提供包括數(shù)據(jù)序列化、狀態(tài)表述等各種形式的數(shù)據(jù)反饋。
OAuth2.0協(xié)議
OAuth協(xié)議為用戶資源的授權(quán)提供了一個安全的、開放而又簡易的標(biāo)準(zhǔn)。與以往的授權(quán)方式不同之處是OAuth的授權(quán)不會使第三方觸及到用戶的用戶名與密碼等敏感信息,即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權(quán)。允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務(wù)提供者的數(shù)據(jù)。OAuth2.0是OAuth協(xié)議的二代版本,為Web應(yīng)用,桌面應(yīng)用和手機(jī)應(yīng)用等提供專門的認(rèn)證流程。
REST服務(wù)和OAuth2.0結(jié)合的開放平臺
2007年5月份,F(xiàn)acebook宣布改版,最早提出了開放平臺的概念,Restful Web應(yīng)用和OAuth2.0結(jié)合的開放平臺是一個流行的模式,國內(nèi)外各大網(wǎng)站都推出了自己的開放API服務(wù)。
本文主要是采用Django REST framework下的OAuth toolkit實(shí)現(xiàn)站內(nèi)數(shù)據(jù)的認(rèn)證,實(shí)現(xiàn)用戶的統(tǒng)一身份認(rèn)證。采用token的實(shí)現(xiàn)方式,用戶在首次連接服務(wù)器時,服務(wù)器驗(yàn)證用戶信息,生成并返回令牌,當(dāng)用戶再次請求數(shù)據(jù)的時候附帶先前服務(wù)器提供的token令牌,令牌中存儲有此次登錄的有效時間,范圍以及用戶信息。通過REST的設(shè)計(jì)模式,對不同的數(shù)據(jù)資源設(shè)計(jì)不同的URI,對資源進(jìn)行的操作由客戶端指定的URI和HTTP協(xié)議動詞的組合來完成數(shù)據(jù)的高效操作。同時通過Token驗(yàn)證返回給用戶對應(yīng)的數(shù)據(jù)相關(guān)權(quán)限,實(shí)現(xiàn)數(shù)據(jù)的安全訪問。
Django REST framework模型分析
Django REST framework框架是建立在Django框架之上的,屬于Django框架的一個中間件,主要實(shí)現(xiàn)數(shù)據(jù)的API操作接口,同時提供多種功能包括權(quán)限控制與用戶認(rèn)證。具體實(shí)現(xiàn)數(shù)據(jù)在客戶端和服務(wù)器之間的安全傳輸,分為以下步驟:
A:數(shù)據(jù)模型建立(model 數(shù)據(jù)序列化)。對于數(shù)據(jù)進(jìn)行建模,通過Django的models.py文件建立需要進(jìn)行數(shù)據(jù)交互的數(shù)據(jù)原型。對于數(shù)據(jù)模型建立序列化方法,方法數(shù)據(jù)的傳輸。
B:創(chuàng)建數(shù)據(jù)訪問接口。對于不同的數(shù)據(jù)資源建立不同的數(shù)據(jù)訪問接口,對于同一數(shù)據(jù)資源建立對應(yīng)的HTTP協(xié)議中定義的方法(PUT,GET,POST,DELETE)。
C:API訪問路由設(shè)置。對不同的數(shù)據(jù)資源建立不同的路由URI,按照REST的思想,同一數(shù)據(jù)資源擁有相同的URI。
Django OAuth Toolkit建立OAuth2.0認(rèn)證
圖1 OAuth2.0認(rèn)證流程
相比于傳統(tǒng)的OAuth2.0的復(fù)雜的配置認(rèn)證,Django OAuth Toolkit完美地提供了方便快捷的OAuth2.0的支持, OAuth2.0的基本流程如圖1所示。
客戶端從資源擁有者(最終用戶)那里請求授權(quán)。授權(quán)請求能夠直接發(fā)送給資源擁有者,或者間接地通過授權(quán)服務(wù)器發(fā)送請求,然后資源擁有者為客戶端授權(quán),給客戶端發(fā)送一個訪問許可(Authorization Code),客戶端出示自己的私有證書(client_ id和client_secret)和上一步拿到的訪問許可,來向授權(quán)服務(wù)器請求一個訪問令牌,授權(quán)服務(wù)器驗(yàn)證客戶端的私有證書和訪問許可的有效性,如果驗(yàn)證有效,則向客戶端發(fā)送一個訪問令牌,訪問令牌包括許可的作用域、有效時間和一些其他屬性信息,客戶端出示訪問令牌向資源服務(wù)器請求受保護(hù)資源,資源服務(wù)器對訪問令牌做出響應(yīng)。
在Django REST framework的OAuth Toolkit支持下,基本的用戶統(tǒng)一身份認(rèn)證及數(shù)據(jù)資源權(quán)限控制實(shí)現(xiàn)流程主要有以下不同:對于當(dāng)前的Django應(yīng)用添加OAuth2支持oauth2_provider,在OAuth的認(rèn)證菜單內(nèi)注冊應(yīng)用程序獲取client_id和client_ secret,相當(dāng)于第三方應(yīng)用在平臺注冊。后面請求受控制資源時攜帶申請的令牌即可。
認(rèn)證模型整體架構(gòu)設(shè)計(jì)
為了實(shí)現(xiàn)用戶的統(tǒng)一身份認(rèn)證和數(shù)據(jù)權(quán)限控制,采用的基本框架是Django支撐的Django REST framework和Django OAuth Toolkit,基本流程如圖2。
認(rèn)證模型實(shí)現(xiàn)步驟
以用戶個人信息的獲取更新為例解釋Django OAuth Toolkit下的OAuth統(tǒng)一身份認(rèn)證及數(shù)據(jù)資源權(quán)限控制。
1.建立用戶數(shù)據(jù)模型
通過Django的model建立用戶的相關(guān)屬性,通過Django集成的命令建立數(shù)據(jù)庫存儲,將用戶信息存入數(shù)據(jù)庫等待API調(diào)用。
2. 第三方應(yīng)用向應(yīng)用平臺注冊應(yīng)用
圖2 Django REST framework和OAuth2.0結(jié)合的認(rèn)證流程
在Django框架下的OAuth2.0中注冊一個應(yīng)用,名稱為wireless, Client type為Confidential, Authorization grant type為Resource Owner Password Credentials Grant,獲取對應(yīng)的client_id和client_secret。
3.在網(wǎng)站注冊用戶
在資源服務(wù)器注冊用戶,用戶名為hacker,并填寫相關(guān)信息。
4.第三方應(yīng)用請求用戶授權(quán)讀取用戶信息
第三方應(yīng)用,以手機(jī)App為例,引導(dǎo)用戶hacker在授權(quán)頁面填寫用戶名密碼以獲取用戶的授權(quán)。
5.用戶授權(quán)給第三方客戶端
用戶hacker在客戶端的授權(quán)頁輸入用戶名和密碼,通過調(diào)用登錄API(POST /api/ login/),向平臺提交授權(quán)用戶的用戶名和密碼以及客戶端的配置信息。
其中需要用到的access_token 即為客戶端訪問用戶數(shù)據(jù)的令牌,expired_in即為令牌的有效時間,時間單位為秒,scope即為該令牌擁有的權(quán)限對數(shù)據(jù)進(jìn)行讀寫操作。
6.客戶端攜帶申請的access_token訪問用戶信息
資源服務(wù)器檢查客戶端提交的access_ token,通過REST的URI標(biāo)識路由到控制器。然后通過認(rèn)證函數(shù)OAuth2Authentication和權(quán)限控制函數(shù)permission_classes驗(yàn)證access_token有效性,如果access_token有效則資源服務(wù)器返回相關(guān)數(shù)據(jù)給客戶端,否則返回認(rèn)證失敗。
如果用戶票據(jù)正確則返回用戶信息,否則提示失敗。
此外OAuth2.0也提供了refresh_token,如果客戶端保存的access_token過期,當(dāng)資源服務(wù)器檢查到該access_token過期時,客戶端可以向授權(quán)服務(wù)器出示client_id和client_ secret以及refresh_token,授權(quán)服務(wù)器鑒定正確性和有效性,鑒定有效則給客戶端分發(fā)一個新的訪問令牌access_token。
OAuth2.0是目前國際通用的授權(quán)方式,認(rèn)證與授權(quán)的流程簡單、安全,提供了安全的統(tǒng)一身份認(rèn)證,通過令牌的方式保護(hù)了數(shù)據(jù)的權(quán)限安全,其也提供了用戶多賬號通用和資源共享的機(jī)制。但是在Web應(yīng)用中,缺少對數(shù)據(jù)的高效封裝操作,Django REST framework作為優(yōu)秀的Web框架Django下的REST框架,通過特定的URI來表示不同的資源,利用HTTP的協(xié)議動詞(POST,GET,PUT,DELETE)實(shí)現(xiàn)對資源的操作,但是缺少數(shù)據(jù)安全性的控制。本文通過前面的實(shí)例分析和測試,得出在Django REST framework框架下包含OAuth2.0認(rèn)證的Django OAuth Toolkit可以結(jié)合二者的優(yōu)點(diǎn),在保證數(shù)據(jù)的高效封裝訪問,提供數(shù)據(jù)的ORM操作和序列化的同時,又確保了數(shù)據(jù)的安全性,對用戶的統(tǒng)一身份認(rèn)證做了深入封裝,是下一代開放平臺優(yōu)先的選擇。
(作者單位為北京師范大學(xué))