1)oauth2.0 提供了四種受權模式,開發者能夠根據本身的業務狀況自由選擇。java
整個開發流程簡述一下:web
一、 在客戶端web項目中構造一個oauth的客戶端請求對象(OAuthClientRequest),在此對象中攜帶客戶端信息(clientId、accessTokenUrl、response_type、redirectUrl),將此信息放入http請求中,重定向到服務端。此步驟對應上圖1json
二、 在服務端web項目中接受第一步傳過來的request,從中獲取客戶端信息,能夠自行驗證信息的可靠性。同時構造一個oauth的code受權許可對象(OAuthAuthorizationResponseBuilder),並在其中設置受權碼code,將此對象傳回客戶端。此步驟對應上圖2瀏覽器
三、 在在客戶端web項目中接受第二步的請求request,從中得到code。同時構造一個oauth的客戶端請求對象(OAuthClientRequest),這次在此對象中不只要攜帶客戶端信息(clientId、accessTokenUrl、clientSecret、GrantType、redirectUrl),還要攜帶接受到的code。再構造一個客戶端請求工具對象(oAuthClient),這個工具封裝了httpclient,用此對象將這些信息以post(必定要設置成post)的方式請求到服務端,目的是爲了讓服務端返回資源訪問令牌。此步驟對應上圖3。(另外oAuthClient請求服務端之後,會自行接受服務端的響應信息。緩存
四、 在服務端web項目中接受第三步傳過來的request,從中獲取客戶端信息和code,並自行驗證。再按照本身項目的要求生成訪問令牌(accesstoken),同時構造一個oauth響應對象(OAuthASResponse),攜帶生成的訪問指令(accesstoken),返回給第三步中客戶端的oAuthClient。oAuthClient接受響應以後獲取accesstoken,此步驟對應上圖4bash
五、 此時客戶端web項目中已經有了從服務端返回過來的accesstoken,那麼在客戶端構造一個服務端資源請求對象(OAuthBearerClientRequest),在此對象中設置服務端資源請求URI,並攜帶上accesstoken。再構造一個客戶端請求工具對象(oAuthClient),用此對象去服務端靠accesstoken換取資源。此步驟對應上圖5服務器
六、 在服務端web項目中接受第五步傳過來的request,從中獲取accesstoken並自行驗證。以後就能夠將客戶端請求的資源返回給客戶端了。app
受權碼模式(authorization code)是功能最完整、流程最嚴密的受權模式。它的特色就是經過客戶端的後臺服務器,與"服務提供商"的認證服務器進行互動。框架
它的步驟以下:工具
(A)用戶訪問客戶端,後者將前者導向認證服務器。
(B)用戶選擇是否給予客戶端受權。
(C)假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection URI),同時附上一個受權碼。
(D)客戶端收到受權碼,附上早先的"重定向URI",向認證服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見。
(E)認證服務器覈對了受權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)。
下面是上面這些步驟所須要的參數。
A步驟中,客戶端申請認證的URI,包含如下參數:
下面是一個例子:
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,包含如下參數:
下面是一個例子:
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz
複製代碼
D步驟中,客戶端向認證服務器申請令牌的HTTP請求,包含如下參數:
下面是一個例子
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步驟中,認證服務器發送的HTTP回覆,包含如下參數:
下面是一個例子:
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"
}
複製代碼
從上面代碼能夠看到,相關參數使用JSON格式發送(Content-Type: application/json)。此外,HTTP頭信息中明確指定不得緩存。
簡化模式(implicit grant type)不經過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了"受權碼"這個步驟,所以得名。全部步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不須要認證。
它的步驟以下:
(A)客戶端將用戶導向認證服務器。
(B)用戶決定是否給於客戶端受權。
(C)假設用戶給予受權,認證服務器將用戶導向客戶端指定的"重定向URI",並在URI的Hash部分包含了訪問令牌。
(D)瀏覽器向資源服務器發出請求,其中不包括上一步收到的Hash值。
(E)資源服務器返回一個網頁,其中包含的代碼能夠獲取Hash值中的令牌。
(F)瀏覽器執行上一步得到的腳本,提取出令牌。
(G)瀏覽器將令牌發給客戶端。
下面是上面這些步驟所須要的參數。
A步驟中,客戶端發出的HTTP請求,包含如下參數:
下面是一個例子。
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
複製代碼
C步驟中,認證服務器迴應客戶端的URI,包含如下參數:
下面是一個例子。
HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
&state=xyz&token_type=example&expires_in=3600
複製代碼
在上面的例子中,認證服務器用HTTP頭信息的Location欄,指定瀏覽器重定向的網址。注意,在這個網址的Hash部分包含了令牌。
根據上面的D步驟,下一步瀏覽器會訪問Location指定的網址,可是Hash部分不會發送。接下來的E步驟,服務提供商的資源服務器發送過來的代碼,會提取出Hash中的令牌。
密碼模式(Resource Owner Password Credentials Grant)中,用戶向客戶端提供本身的用戶名和密碼。客戶端使用這些信息,向"服務商提供商"索要受權。
在這種模式中,用戶必須把本身的密碼給客戶端,可是客戶端不得儲存密碼。這一般用在用戶對客戶端高度信任的狀況下,好比客戶端是操做系統的一部分,或者由一個著名公司出品。而認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式。
它的步驟以下:
(A)用戶向客戶端提供用戶名和密碼。
(B)客戶端將用戶名和密碼發給認證服務器,向後者請求令牌。
(C)認證服務器確認無誤後,向客戶端提供訪問令牌。
B步驟中,客戶端發出的HTTP請求,包含如下參數:
下面是一個例子。
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=johndoe&password=A3ddj3w
複製代碼
C步驟中,認證服務器向客戶端發送訪問令牌,下面是一個例子。
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"
}
複製代碼
上面代碼中,各個參數的含義參見《受權碼模式》一節。
整個過程當中,客戶端不得保存用戶的密碼。
客戶端模式(Client Credentials Grant)指客戶端以本身的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,用戶直接向客戶端註冊,客戶端以本身的名義要求"服務提供商"提供服務,其實不存在受權問題。
它的步驟以下:
(A)客戶端向認證服務器進行身份認證,並要求一個訪問令牌。
(B)認證服務器確認無誤後,向客戶端提供訪問令牌。
A步驟中,客戶端發出的HTTP請求,包含如下參數:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
複製代碼
認證服務器必須以某種方式,驗證客戶端身份。
B步驟中,認證服務器向客戶端發送訪問令牌,下面是一個例子。
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,
"example_parameter":"example_value"
}
複製代碼
若是用戶訪問的時候,客戶端的"訪問令牌"已通過期,則須要使用"更新令牌"申請一個新的訪問令牌。
客戶端發出更新令牌的HTTP請求,包含如下參數:
下面是一個例子。
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
複製代碼