Android OAuth2.0(開放授權Open Authorization)

參考
知乎 OAuth 授權的工作原理是怎樣的酪捡?足夠安全嗎耕肩?
阮一峰 理解OAuth 2.0

一典奉、第三方應用如何授權才安全

1.例一
有一個"云沖印"的網(wǎng)站悼沿,可以將用戶儲存在Google的照片屿笼,沖印出來牺荠。用戶為了使用該服務,必須讓"云沖印"讀取自己儲存在Google上的照片驴一。問題是只有得到用戶的授權志电,Google才會同意"云沖印"讀取這些照片。那么蛔趴,"云沖印"怎樣獲得用戶的授權呢挑辆?

傳統(tǒng)方法是,用戶將自己的Google用戶名和密碼孝情,告訴"云沖印"鱼蝉,后者就可以讀取用戶的照片了。這樣的做法有以下幾個嚴重的缺點箫荡。

  • "云沖印"為了后續(xù)的服務魁亦,會保存用戶的密碼,這樣很不安全羔挡。
  • Google不得不部署密碼登錄洁奈,而我們知道,單純的密碼登錄并不安全绞灼。
  • "云沖印"擁有了獲取用戶儲存在Google所有資料的權力利术,用戶沒法限制"云沖印"獲得授權的范圍和有效期。
  • 用戶只有修改密碼低矮,才能收回賦予"云沖印"的權力印叁。但是這樣做,會使得其他所有獲得用戶授權的第三方應用程序全部失效。
  • 只要有一個第三方應用程序被破解轮蜕,就會導致用戶密碼泄漏昨悼,以及所有被密碼保護的數(shù)據(jù)泄漏。

OAuth就是為了解決上面這些問題而誕生的跃洛。

2.例二
新浪微博就是你的家率触。偶爾你會想讓一些人(第三方應用)去你的家里幫你做一些事,或取點東西汇竭。你可以復制一把鑰匙(用戶名和密碼)給他們葱蝗,但這里有三個問題:

  • 別人拿了鑰匙后可以去所有的房間
  • 別人拿到你的鑰匙后也許會不小心丟到,甚至故意送到它人手里韩玩。這樣你都不知到誰有你家鑰匙。
  • 過一段時間你也許會想要回自己的鑰匙陆馁,但別人不還怎么辦找颓?

OAuth 是高級鑰匙:

  • 你可以配置不同權限的鑰匙。有些只能進大廳(讀取你的微博流)叮贩。有些鑰匙可以進儲藏柜(讀取你的相片)
  • 鑰匙上帶著指紋驗證的(指紋 = appkey)击狮。 收到鑰匙的人只能自己用,不能轉讓
  • 你可以遠程廢除之前發(fā)出的鑰匙
二益老、流程

參考簡述 OAuth 2.0 的運作流程

假如我有一個網(wǎng)站彪蓬,你是我網(wǎng)站上的訪客,看了文章想留言表示「朕已閱」捺萌,留言時發(fā)現(xiàn)有這個網(wǎng)站的帳號才能夠留言档冬,此時給了你兩個選擇:一個是在我的網(wǎng)站上注冊擁有一個新賬戶,然后用注冊的用戶名來留言桃纯;一個是使用 github 帳號登錄酷誓,使用你的 github 用戶名來留言。前者你覺得過于繁瑣态坦,于是慣性地點擊了 github 登錄按鈕盐数,此時 OAuth 認證流程就開始了。

需要明確的是伞梯,即使用戶剛登錄過 github玫氢,我的網(wǎng)站也不可能向 github 發(fā)一個什么請求便能夠拿到訪客信息,這顯然是不安全的谜诫。就算用戶允許你獲取他在 github 上的信息漾峡,github 為了保障用戶信息安全,也不會讓你隨意獲取喻旷。所以操作之前灰殴,我的網(wǎng)站與 github 之間需要要有一個協(xié)商。

1. 網(wǎng)站和 Github 之間的協(xié)商
Github 會對用戶的權限做分類,比如讀取倉庫信息的權限牺陶、寫入倉庫的權限伟阔、讀取用戶信息的權限、修改用戶信息的權限等等掰伸。如果我想獲取用戶的信息皱炉,Github 會要求我,先在它的平臺上注冊一個應用狮鸭,在申請的時候標明需要獲取用戶信息的哪些權限合搅,用多少就申請多少,并且在申請的時候填寫你的網(wǎng)站域名歧蕉,Github 只允許在這個域名中獲取用戶信息灾部。

此時我的網(wǎng)站已經(jīng)和 Github 之間達成了共識,Github 也給我發(fā)了兩張門票惯退,一張門票叫做 Client Id赌髓,另一張門票叫做 Client Secret。

2. 用戶和 Github 之間的協(xié)商
用戶進入我的網(wǎng)站催跪,點擊 github 登錄按鈕的時候锁蠕,我的網(wǎng)站會把上面拿到的 Client Id 交給用戶,讓他進入到 Github 的授權頁面懊蒸,Github 看到了用戶手中的門票荣倾,就知道這是我的網(wǎng)站讓他過來的,于是它就把我的網(wǎng)站想要獲取的權限擺出來骑丸,并詢問用戶是否允許我獲取這些權限舌仍。

// 用戶登錄 github,協(xié)商
GET //github.com/login/oauth/authorize

// 協(xié)商憑證
params = {
  client_id: "xxxx",
  redirect_uri: "http://my-website.com"
}

如果用戶覺得我的網(wǎng)站要的權限太多通危,或者壓根就不想我知道他這些信息抡笼,選擇了拒絕的話,整個 OAuth 2.0 的認證就結束了黄鳍,認證也以失敗告終推姻。如果用戶覺得 OK,在授權頁面點擊了確認授權后框沟,頁面會跳轉到我預先設定的 redirect_uri 并附帶一個蓋了章的門票 code藏古。

// 協(xié)商成功后帶著蓋了章的 code
Location: http://my-website.com?code=xxx

這個時候,用戶和 Github 之間的協(xié)商就已經(jīng)完成忍燥,Github 也會在自己的系統(tǒng)中記錄這次協(xié)商拧晕,表示該用戶已經(jīng)允許在我的網(wǎng)站訪問上直接操作和使用他的部分資源。

3. 告訴 Github 我的網(wǎng)站要來拜訪了
第二步中梅垄,我們已經(jīng)拿到了蓋過章的門票 code厂捞,但這個 code 只能表明,用戶允許我的網(wǎng)站從 github 上獲取該用戶的數(shù)據(jù),如果我直接拿這個 code 去 github 訪問數(shù)據(jù)一定會被拒絕靡馁,因為任何人都可以持有 code欲鹏,github 并不知道 code 持有方就是我本人。

還記得之前申請應用的時候 github 給我的兩張門票么臭墨,Client Id 在上一步中已經(jīng)用過了赔嚎,接下來輪到另一張門票 Client Secret。

// 網(wǎng)站和 github 之間的協(xié)商
POST //github.com/login/oauth/access_token

// 協(xié)商憑證包括 github 給用戶蓋的章和 github 發(fā)給我的門票
params = {
  code: "xxx",
  client_id: "xxx",
  client_secret: "xxx",
  redirect_uri: "http://my-website.com"
}

拿著用戶蓋過章的 code 和能夠標識個人身份的 client_id胧弛、client_secret 去拜訪 github尤误,拿到最后的綠卡 access_token。

// 拿到最后的綠卡
response = {
  access_token: "e72e16c7e42f292c6912e7710c838347ae178b4a"
  scope: "user,gist"
  token_type: "bearer",
  refresh_token: "xxxx"
}

4. 用戶開始使用 github 帳號在我的頁面上留言
上一步 github 已經(jīng)把最后的綠卡 access_token 給我了结缚,通過 github 提供的 API 加綠卡就能夠訪問用戶的信息了损晤,能獲取用戶的哪些權限在 response 中也給了明確的說明,scope 為 user 和 gist红竭,也就是只能獲取 user 組和 gist 組兩個// 訪問用戶數(shù)據(jù)

//綠卡 access_token
GET //api.github.com/user?access_token=e72e16c7e42f
292c6912e7710c838347ae178b4a

// 告訴我用戶的名字和郵箱
response = {
  username: "barretlee",
  email: "barret.china@gmail.com"
}小組的權限尤勋,user 組中就包含了用戶的名字和郵箱等信息了。

整個 OAuth2 流程在這里也基本完成了德崭,文章中的表述很粗糙斥黑,比如 access_token 這個綠卡是有過期時間的揖盘,如果過期了需要使用 refresh_token 重新簽證眉厨。

三、詳解

1.名詞解釋

  • Third-party application:
    第三方應用程序兽狭,又稱"客戶端"(client)憾股,即例子中的"云沖印"或網(wǎng)站。
  • HTTP service:
    HTTP服務提供商箕慧,本文中簡稱"服務提供商"服球,即上一節(jié)例子中的Google或GitHub。
  • Resource Owner:
    資源所有者颠焦,又稱"用戶"(user)斩熊。
  • User Agent:
    用戶代理,本文中就是指瀏覽器伐庭。
  • Authorization server:
    認證服務器粉渠,即服務提供商專門用來處理認證的服務器。
  • Resource server:
    資源服務器圾另,即服務提供商存放用戶生成的資源的服務器霸株。它與認證服務器,可以是同一臺服務器集乔,也可以是不同的服務器去件。

2.授權模式
客戶端必須得到用戶的授權(authorization grant),才能獲得令牌(access token)。OAuth 2.0定義了四種授權方式尤溜。

  • 授權碼模式(authorization code)
  • 簡化模式(implicit)
  • 密碼模式(resource owner password credentials)
  • 客戶端模式(client credentials)

3.授權碼模式
授權碼模式(authorization code)是功能最完整倔叼、流程最嚴密的授權模式。它的特點就是通過客戶端的后臺服務器靴跛,與"服務提供商"的認證服務器進行互動缀雳。它的步驟如下:
(A)用戶訪問客戶端,后者將前者導向認證服務器梢睛。
(B)用戶選擇是否給予客戶端授權肥印。
(C)假設用戶給予授權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection URI)绝葡,同時附上一個授權碼深碱。
(D)客戶端收到授權碼,附上早先的"重定向URI"藏畅,向認證服務器申請令牌敷硅。這一步是在客戶端的后臺的服務器上完成的,對用戶不可見愉阎。
(E)認證服務器核對了授權碼和重定向URI绞蹦,確認無誤后,向客戶端發(fā)送訪問令牌(access token)和更新令牌(refresh token)榜旦。

A步驟中幽七,客戶端申請認證的URI,包含以下參數(shù):

  • response_type:表示授權類型溅呢,必選項澡屡,此處的值固定為"code"
  • client_id:表示客戶端的ID,必選項
  • redirect_uri:表示重定向URI咐旧,可選項
  • scope:表示申請的權限范圍驶鹉,可選項
  • state:表示客戶端的當前狀態(tài),可以指定任意值铣墨,認證服務器會原封不動地返回這個值室埋。

下面是一個例子。

GET /authorize?response_type=code&client_id=s6BhdRkqt3
&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb 
HTTP/1.1 Host: server.example.com

C步驟中伊约,服務器回應客戶端的URI姚淆,包含以下參數(shù):

  • code:表示授權碼,必選項碱妆。該碼的有效期應該很短肉盹,通常設為10分鐘,客戶端只能使用該碼一次,否則會被授權服務器拒絕。該碼與客戶端ID和重定向URI,是一一對應關系也殖。
  • state:如果客戶端的請求中包含這個參數(shù)窍蓝,認證服務器的回應也必須一模一樣包含這個參數(shù)腋颠。

下面是一個例子。

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
          &state=xyz

D步驟中吓笙,客戶端向認證服務器申請令牌的HTTP請求淑玫,包含以下參數(shù):

  • grant_type:表示使用的授權模式,必選項面睛,此處的值固定為"authorization_code"絮蒿。
  • code:表示上一步獲得的授權碼,必選項叁鉴。
  • redirect_uri:表示重定向URI土涝,必選項,且必須與A步驟中的該參數(shù)值保持一致幌墓。
  • client_id:表示客戶端ID但壮,必選項。

下面是一個例子常侣。

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

E步驟中蜡饵,認證服務器發(fā)送的HTTP回復,包含以下參數(shù):

  • access_token:表示訪問令牌胳施,必選項溯祸。
  • token_type:表示令牌類型,該值大小寫不敏感巾乳,必選項您没,可以是bearer類型或mac類型鸟召。
  • expires_in:表示過期時間胆绊,單位為秒。如果省略該參數(shù)欧募,必須其他方式設置過期時間压状。
  • refresh_token:表示更新令牌,用來獲取下一次的訪問令牌跟继,可選項种冬。
  • scope:表示權限范圍,如果與客戶端申請的范圍一致舔糖,此項可省略娱两。

下面是一個例子。

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }
四金吗、應用

參考
android 新浪微博Oauth2.0認證以及自定義webview認證
android新浪微博Oauth2.0認證以及登錄
Android中的OAuth2.0——QQ第三方授權登錄

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末十兢,一起剝皮案震驚了整個濱河市趣竣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旱物,老刑警劉巖遥缕,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宵呛,居然都是意外死亡单匣,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門宝穗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來户秤,“玉大人,你說我怎么就攤上這事逮矛』⒓桑” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵橱鹏,是天一觀的道長膜蠢。 經(jīng)常有香客問我,道長莉兰,這世上最難降的妖魔是什么挑围? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮糖荒,結果婚禮上杉辙,老公的妹妹穿的比我還像新娘。我一直安慰自己捶朵,他們只是感情好蜘矢,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著综看,像睡著了一般品腹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上红碑,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天舞吭,我揣著相機與錄音,去河邊找鬼析珊。 笑死羡鸥,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的忠寻。 我是一名探鬼主播惧浴,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼奕剃!你這毒婦竟也來了衷旅?” 一聲冷哼從身側響起哑姚,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芜茵,沒想到半個月后叙量,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡九串,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年绞佩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猪钮。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡品山,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出烤低,到底是詐尸還是另有隱情肘交,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布扑馁,位于F島的核電站涯呻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏腻要。R本人自食惡果不足惜复罐,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雄家。 院中可真熱鬧效诅,春花似錦、人聲如沸趟济。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顷编。三九已至戚炫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間勾效,已是汗流浹背嘹悼。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工叛甫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留层宫,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓其监,卻偏偏與公主長得像萌腿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抖苦,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理毁菱,服務發(fā)現(xiàn)米死,斷路器,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • OAuth是一個關于授權(authorization)的開放網(wǎng)絡標準贮庞,在全世界得到廣泛應用峦筒,目前的版本是2.0版。...
    夕望有你閱讀 283評論 1 2
  • OAuth是一個關于授權(authorization)的開放網(wǎng)絡標準窗慎,在全世界得到廣泛應用物喷,目前的版本是2.0版。...
    謝謝寫閱讀 743評論 0 1
  • OAuth是一個關于授權(authorization)的開放網(wǎng)絡標準遮斥,在全世界得到廣泛應用峦失,目前的版本是2.0版。...
    常曉曉閱讀 776評論 0 0
  • 吃過面包片的多少都會涂抹果醬提一下味道,今天小編帶您學習草莓醬的制作较屿,不用再去超市購買隧魄,自己就可以做出純正的草莓醬...
    家庭涮烤驛站閱讀 338評論 0 1