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