本文介紹案頭和移動端的Native應用如何通過OAuth 2.0扮演登入使用者訪問阿里雲API。
前提條件
Native應用扮演登入使用者訪問阿里雲首先需要建立應用,為應用提供恰當的名稱、OAuth範圍、回調地址等關鍵資訊。詳情請參見建立應用。由於Native應用運行在非可信環境,無法有效保護應用密鑰,因此Native應用不使用應用密鑰。
應用建立成功之後,可以在雲帳號內直接扮演使用者。
基本流程

使用者通過瀏覽器登入Native應用。
Native應用重新導向到阿里雲OAuth 2.0服務並將URL返回給瀏覽器。
說明如果使用者還未登入,則會進一步重新導向到阿里雲登入服務。
使用者通過瀏覽器登入阿里雲OAuth 2.0服務並申請授權碼。
阿里雲OAuth 2.0服務重新導向到Native應用並返回授權碼給瀏覽器。
瀏覽器通過Native應用使用授權碼向阿里雲OAuth 2.0服務申請代表使用者身份的令牌。
阿里雲OAuth 2.0服務向Native應用返回令牌。
Native應用通過擷取的令牌向阿里雲發起訪問API的請求。
說明由於令牌可以代表使用者身份,因此應用可以訪問目前使用者的資源。
Proof Key機制的原理
Native應用支援Proof Key機制,用於每次擷取授權碼以及用授權碼換取存取權杖。
這一機制可以減輕針對授權碼截獲的攻擊。
Native應用產生:
code_verifier,並儲存好這個隨機字串。說明code_verifier是一個高熵值的隨機字串,其取值為:[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~",長度限制為:43~128個字元。應用根據
transform的方式選擇產生code_challenge。應用在申請授權碼的同時提交:code_challenge以及產生code_challenge的方式。code_challenge = transform(code_verifier, [Plain|S256])方式
取值
plain如果
transform的方式選擇為plain,那麼code_challenge與code_verifier的值相同。S256如果
transform的方式選擇為S256,那麼code_challenge等於code_verifier的SHA256雜湊值。code_challenge=BASE64URL-Encode(SHA256(ASCII(code_verifier)))說明雜湊演算法的輸入為
code_verifier的ASCII編碼串,雜湊演算法的輸出字串需要進行BASE64-URL編碼。code_challenge選擇方式計算樣本:如果應用採用方式為S256,產生
code_verifier的值為dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk,那麼code_challenge為E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM。應用擷取授權碼後,在使用授權碼換取存取權杖時,服務端通過計算判斷是否頒發令牌。
授權碼需包括
code_verifier,服務端按照應用選擇的transform方式對code_verifier進行計算,將結果與code_challenge進行對比,如果一致則頒發存取權杖。
擷取存取權杖
Native應用通過瀏覽器將使用者重新導向到阿里雲OAuth 2.0服務從而擷取授權碼。
授權碼的請求地址:
https://signin.alibabacloud.com/oauth2/v1/auth。表 1. 請求參數 參數名稱
是否必選
描述
client_id
是
應用的身份ID。
redirect_uri
是
建立應用的重新導向URI之一。
response_type
是
傳回型別。根據OAuth 2.0協議,目前支援設定此參數的取值為code。
scope
否
空格分隔的OAuth範圍列表。如不指定此參數取值,則預設為應用的全部OAuth範圍。
state
否
應用通過state參數實現多種目的,例如:狀態保持、作為nonce使用從而減少CSRF威脅等。state如果設定為任一字元串,阿里雲OAuth 2.0服務會將請求中的state參數以及取值原樣放到返回參數中以供後續使用。
code_challenge_method
否
如果不指定此參數,則預設取值為plain。
code_challenge
否
根據用戶端指定的code_challenge_method,對隨機產生的code_verifier進行轉換和編碼,轉換的結果作為code_challenge參數的值在授權碼請求中使用。
說明如果不指定此參數,則無法使用Proof Key機制,在使用授權碼換取令牌時也不需要指定相應的code_verifier,若授權碼被截獲可以直接被用於換取存取權杖。
prompt
否
該參數用於指定伺服器是否需要提示使用者進行授權操作。
如果指定,會強制要求使用者進行授權,即使該阿里雲帳號已經做過授權,也需要重新授權。如果不指定,則只在該阿里雲帳號第一次使用該應用時要求授權。
取值:
admin_consent,表示服務端會在向用戶端返回資訊之前展示授權頁面。請求樣本
https://signin.alibabacloud.com/oauth2/v1/auth? client_id=98989**** &redirect_uri=meeting%3A%2F%2Fauthorize%2F &response_type=code &scope=openid%20%2Fworksuite%2Fuseraccess &state=123456**** &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSst**** &code_challenge_method=S256返回樣本
GET HTTP/1.1 302 Found Location: meeting://authorize/?code=ABAFDGDFXYZW888&state=123456****Native應用使用授權碼向阿里雲OAuth 2.0服務申請代表使用者身份的令牌。
換取存取權杖的請求地址:
https://oauth.alibabacloud.com/v1/token。表 2. 請求參數 參數名稱
是否必選
描述
code
是
初始請求中擷取的授權碼。
client_id
是
應用的身份ID。
redirect_uri
是
初始請求中設定的參數。
grant_type
是
根據OAuth 2.0協議, 取值為authorization_code。
code_verifier
否
初始請求中產生的code_verifier,對應於授權碼請求中的code_challenge參數。
請求樣本
POST /v1/token HTTP/1.1 Host: oauth.alibabacloud.com Content-Type: application/x-www-form-urlencoded code=ABAFDGDFXYZW888& client_id=98989**** redirect_uri=meeting://authorize/& grant_type=authorization_code& code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk表 3. 返回參數 參數名稱
描述
access_token
存取權杖。存取權杖可以代表使用者身份,應用使用此存取權杖來訪問阿里雲API。應用不需要理解存取權杖的含義,直接使用即可。
expires_in
存取權杖的剩餘有效時間,單位為秒。
token_type
存取權杖的類型。取值為Bearer。
id_token
身份令牌。id_token為OAuth簽名的JWT(JSON Web Token)。如果初始請求的scope參數包含了openid,則返回身份令牌。
refresh_token
重新整理權杖。此參數可以直接使用,Native應用不需要指定存取權杖的值,可以直接獲得重新整理權杖。
返回樣本
{ "access_token": "eyJraWQiOiJrMTIzNCIsImVuYyI6****", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "Ccx63VVeTn2dxV7ovXXfLtAqLLERA****", "id_token": "eyJhbGciOiJIUzI1****" }
擷取新的存取權杖
換取存取權杖的請求地址:https://oauth.alibabacloud.com/v1/token。
參數名稱 | 是否必選 | 描述 |
refresh_token | 是 | 用授權碼換取存取權杖時獲得的重新整理權杖。 |
client_id | 是 | 應用的身份ID。 |
grant_type | 是 | 根據OAuth 2.0協議,取值為refresh_token。 |
請求樣本
POST /v1/token HTTP/1.1
Host: oauth.alibabacloud.com
Content-Type: application/x-www-form-urlencoded
refresh_token=Ccx63VVeTn2dxV7ovXXfLtAqLLERAH****
client_id=98989****
grant_type=refresh_token參數名稱 | 描述 |
access_token | 新的存取權杖。應用使用新的存取權杖來訪問阿里雲API。 |
expires_in | 存取權杖的剩餘有效時間,單位為秒。 |
token_type | 存取權杖的類型。取值為Bearer。 |
返回樣本
{
"access_token": "eyJraWQiOiJrMTIzNCIsImVuYyI6****",
"token_type": "Bearer",
"expires_in": 3600,
} 本次請求的傳回值與用授權碼換取存取權杖的傳回值一致,但不包含refresh_token和id_token。
撤銷重新整理權杖
Native應用擷取了重新整理權杖後,在使用者退出登入應用時或使用者將自己的帳號從應用中移除時,必須撤銷重新整理權杖。
撤銷重新整理權杖的請求地址:https://oauth.alibabacloud.com/v1/revoke。
參數名稱 | 是否必選 | 描述 |
token | 是 | 需要撤銷的重新整理權杖。 |
client_id | 是 | 應用的身份ID。 |