OAuth有一些定義:web
OAuth 2.0是一個委託協議, 它可讓那些控制資源的人容許某個應用以表明他們來訪問他們控制的資源, 注意是表明這些人, 而不是假冒或模仿這些人. 這個應用從資源的全部者那裏得到到受權(Authorization)和access token, 隨後就可使用這個access token來訪問資源.瀏覽器
(這裏提到的假冒或模仿就是指在客戶端複製一份用戶名和密碼,從而獲取相應的權限)。安全
OAuth 2.0是一個開放的協議, 它容許使用簡單和標準的方法從Web, 移動或桌面應用來進行安全的受權(Authorization).服務器
從這些定義能夠看出來, OAuth2 是關於受權(Authorization)的, 客戶端應用能夠請求access token, 使用這個token就能夠訪問API資源了.ide
由於有不少種類客戶端應用的存在, 例如ASP.NET Core MVC, Angular, WPF 等等, 它們都是不一樣的應用類型, 因此, OAuth2 定義了不一樣類型的客戶端應用應該如何安全的完成受權. OAuth2標準還定義了一些端點, 而且定義了針對不一樣類型的客戶端應用如何使用這些端點.優化
Identity Server 4 和 Azure AD 都實現了OAuth 2.0 標準.spa
可是上面提到的access token只能用來訪問資源, 它沒法被用來登陸客戶端應用. 登陸這種操做叫作認證/身份驗證(Authentication), 而OpenID Connect則能夠完成這項工做.3d
OpenID Connect是創建在OAuth2協議上的一個簡單的身份標識層, 因此OpenID Connect兼容OAuth2. code
使用OpenID Connect, 客戶端應用能夠請求一個叫identity token的token, 它會和access token一同返回給客戶端應用. 這個identity token就能夠被用來登陸客戶端應用程序, 而這個客戶端應用還可使用access token來訪問API資源.blog
OpenID Connect還定義了一個UserInfo端點, (OAuth2定義了Authorization端點和Token端點)它容許客戶端應用獲取用戶的額外信息.
此外它還定義了不一樣類型的應用如何從身份識別提供商(IDP)安全的獲取這些token.
綜上, OpenID Connect是更高級的協議, 它擴展並替代了OAuth2. 儘管如今咱們常常說咱們在使用OAuth2來保護API, 其實更準確的說, 大多數狀況下, 咱們使用的是OpenID Connect.
若是到如今仍是不明白OAuth2和OpenID Connect也不要緊, 這不是幾句話就能描述清楚的東西. 本文我進一步介紹OAuth 2.0.
OAuth2的目標就是讓客戶端應用能夠表明資源全部者(一般是用戶)來訪問被保護的資源:
前面提到OAuth2裏面, 最終用戶能夠委派他的一部分權限給客戶端應用來表明最終用戶來訪問被保護的資源. 可是要完成這件事, 還須要一個橋樑來鏈接客戶端應用和被保護資源. 這個組件叫作受權服務器(Authorization Server, AS). 這個受權服務器也許就是資源服務器, 可是大多數狀況下它們是不一樣的服務器.
受權服務器(AS)是被受保護的資源所信任的, 它能夠發行具備特定目的的安全憑據給客戶端應用, 這個憑據叫作OAuth的 access token.
想要得到access token, 客戶端應用首先要把資源全部者發送給受權服務器
首先客戶端須要得到權限, 它可能有兩種方式來得到權限: 能夠從資源全部者那裏直接得到權限, 也可讓受權服務器做爲中介, 從受權服務器那裏間接的得到權限. (上面這個圖中描述的是從資源受權者直接得到權限的流程).
若是使用受權服務器做爲中介的話, 客戶端須要把資源全部者發送到受權服務器(能夠理解爲最終用戶使用的瀏覽器被重定向到了受權服務器), 而後資源全部者在這能夠對客戶端應用進行受權.
這時資源全部者要經過身份認證進入受權服務器, 一般還會有一個是否贊成受權客戶端應用請求的選項, 點擊贊成後就受權了. 而從客戶端應用的角度講呢, 它能夠向資源全部者請求他一部分的功能和範圍(scope), 在未來, 資源全部者可能會逐漸減小它所擁有的功能和範圍.
到這裏, 上面寫的這個動做/東西叫作受權(authorization grant).
一旦執行了受權動做也就是客戶端獲得了受權(這個受權是一個能夠表明資源全部者權限的憑據), 客戶端即可以從受權服務器請求access token了. 這個access token就能夠被用來訪問被保護的資源了.
下圖是使用受權服務器做爲中介的流程圖, 除了受權, 其它部分和上圖表達的都是一個意思:
受權 (authorization grant) 是一個表明着資源全部者權限的憑據, 它能夠被客戶端應用來獲取access token. OAuth2裏面定義了4種類型的受權, 分別是: auhtorization code, implicit, resource owner password credentials, client credentials. OAuth2還定義了一個擴展機制以便定義其它的受權類型.
用一句話描述就是, 受權(Authorization Grant)就是獲取token的方法.
Authorization Code是使用受權服務器做爲客戶端和資源全部者的中介來獲取的. 因此這裏不是採用直接從資源全部者得到受權的方式, 而是採用受權服務器做爲中介的方式. 在受權服務器把資源全部者送回到(重定向)客戶端的時候帶着這個臨時的憑據: authorization code (我暫時叫它受權碼吧), 它就表明着資源全部者委託給客戶端應用的權限.
Authorization code在安全方面有一些重要的優勢: 能夠對客戶端應用進行身份認證; access token是直接發送到客戶端應用的, 不通過資源全部者的瀏覽器, 因此不會暴露access token給外界, 包括資源全部者.
Implicit, 我叫它隱式受權吧. 它是Authorization Code的一個簡化版本, 它針對瀏覽器內的客戶端應用(例如js, angular的應用)進行了優化. 在implicit流程裏, 沒有給客戶端發送受權碼(authorization code), 而是直接給它發送了access token. 之因此叫這種受權類型implicit, 是由於流程裏並無發行任何中間憑據.
在implicit流程裏發行access token的時候, 受權服務器並無對客戶端應用進行身份認證. 某些狀況下, 客戶端的身份能夠經過帶着access token重定向回客戶端的URI來驗證. acces token可能會暴露給任何使用該瀏覽器的人或者應用.
Implicit受權確實能夠提升瀏覽器內應用的響應性和效率, 畢竟它減小了來回往返的次數. 可是方即可能會帶來風險, 建議若是能夠的話儘可能使用Authorization Code, 固然這個須要本身去權衡.
Resource Owner Password Credentials, 資源全部者密碼憑據. 顧名思義, 能夠直接使用密碼憑據(用戶名和密碼)做爲受權來得到access token. 只有當資源全部者和客戶端之間高度信任的時候而且其它受權方式不可用的時候纔可使用這種受權方式.
這裏資源全部者的憑據只應該用於一次請求並用於交換access token. 這種受權方式可讓客戶端免於存儲資源全部者的憑據(若是之後還須要使用的話), 經過交換一個長期有效的access token或refresh token均可以達到這種效果.
Client Credentials. 有時候, 資源或者叫資源服務器並不屬於某個最終用戶, 也就是沒有資源全部者對該資源負責. 可是客戶端應用確定仍是要訪問這些資源, 這時候就只能使用Client Credentials這種受權方式了.
OAuth2的4個角色前面已經介紹過, 分別是: 資源全部者 Resource Owner, 客戶端 Client, 被保護資源 Protected Resource, 和 受權服務器 Authorization Server.
而OAuth2的組件, 前面也都有提到過, 它們是: Access Token, Refresh Token 和 Scope (範圍).
下面簡單介紹下這幾個組件.
Access Token: 有時候只被叫作token, 它是用來訪問被保護資源的憑據. 它是一個字符串, 它表明了給客戶頒發的受權, 也就是委託給客戶的權限. OAuth2自己並無對access token的格式或內容進行定義. 可是access token裏面要描述出資源全部者授予的訪問權限的範圍和持續時間.
Access Token 一般對客戶端應用是不透明的, 也就是說客戶端無需去查看access token. 客戶端的任務就是把它展現給被保護的資源. 其實access token在整個OAuth2系統裏對任何角色都是不透明的, 受權服務器的任務只是發行token, 而被保護資源的任務是驗證token. 可是它們都必須理解access token的構成, 並知道access token表明了什麼. 而客戶端對於access token應該是徹底健忘的.
Scopes: OAuth2的scope表示被保護資源那裏的一套權限. 在OAuth2裏面, scope用區分大小寫的字符串表示, 能夠用空格做爲分隔符來表示多個scope. 這些字符串由受權服務器來定義. 而scope字符串的格式和結構在OAuth2裏並無定義.
Scope對於限制客戶端應用的訪問權限有很重要的做用. 客戶端應用能夠請求一些scopes, 而受權服務器能夠容許資源全部者受權或者拒絕特定的scopes. Scope還具備疊加性.
Refresh Token: Refresh Token是用來得到Access Token的憑據. 和acces token差很少, refresh token也是由受權服務器發行給客戶端應用的, 客戶端不知道也不關心refresh token裏面有啥. 但與access token不一樣的是, refresh token不會被髮送給被保護的資源. 客戶端是用refresh token來請求新的access token (尤爲是當如今的access token過時或者失效時), 但這個過程就不須要資源全部者的參與了. Refresh Token是可選的, 受權服務器會酌情發行refresh token, 若是須要的話, refresh token是在發行access token一同返回的.
此外refresh token還具有讓客戶端應用逐漸下降訪問權限的能力.
經過refresh token來取得新的access token的流程以下:
另一張彩色圖:
這張彩圖的中文意思是: 客戶端使用當前access token訪問被保護資源的時候, access token失效或者過時了, 這是從被保護資源返回了一個錯誤響應; 而後客戶端使用refresh token向受權服務器請求了一個新的access token; 獲得新的access token後, 客戶端使用新的access token請求被保護資源, 這時資源就能夠被正常的返回給客戶端了.
OAuth2定義了一套端點(Endpoint), 端點就是web服務器的一個訪問路徑URI.
OAuth2定義的端點有受權端點, Token端點, 它們都在受權服務器上.
OAuth2沒有定義這些端點URI應該如何被發現和文檔的結構.
受權端點(authorization endpoint)是用來和資源全部者交互的, 資源全部者在這裏進行登陸(身份認證), 而後經過該端點能夠對客戶端進行受權(authorization grant). 受權服務器首先要驗證資源全部者的身份, 可是驗證的方式並不在OAuth2的協議範圍內.
Token端點(token endpoint), 客戶端經過向token端點展現它的受權(auhtorization grant)或refresh token來獲取access token. 除了implicit以外全部的受權類型都須要使用該端點, 由於implicit的access token是直接發行的.
本篇文章先到這. 下篇文章再簡單介紹一下OpenId Connect.
那四種受權類型具體的詳細流程將在介紹Identity Server 4的時候一同介紹.