Native應(yīng)用登錄阿里云
本文介紹桌面和移動(dòng)端的Native應(yīng)用如何通過OAuth 2.0扮演登錄用戶訪問阿里云API。
前提條件
Native應(yīng)用扮演登錄用戶訪問阿里云首先需要?jiǎng)?chuàng)建應(yīng)用,為應(yīng)用提供恰當(dāng)?shù)拿Q、OAuth范圍、回調(diào)地址等關(guān)鍵信息。詳情請(qǐng)參見創(chuàng)建應(yīng)用。由于Native應(yīng)用運(yùn)行在非可信環(huán)境,無法有效保護(hù)應(yīng)用密鑰,因此Native應(yīng)用不使用應(yīng)用密鑰。
應(yīng)用創(chuàng)建成功之后,可以在云賬號(hào)內(nèi)直接扮演用戶。
基本流程
![基本流程](https://help-static-aliyun-doc.aliyuncs.com/assets/img/9286643751/p14376.png)
用戶通過瀏覽器登錄Native應(yīng)用。
Native應(yīng)用重定向到阿里云OAuth 2.0服務(wù)并將URL返回給瀏覽器。
說明如果用戶還未登錄,則會(huì)進(jìn)一步重定向到阿里云登錄服務(wù)。
用戶通過瀏覽器登錄阿里云OAuth 2.0服務(wù)并申請(qǐng)授權(quán)碼。
阿里云OAuth 2.0服務(wù)重定向到Native應(yīng)用并返回授權(quán)碼給瀏覽器。
瀏覽器通過Native應(yīng)用使用授權(quán)碼向阿里云OAuth 2.0服務(wù)申請(qǐng)代表用戶身份的令牌。
阿里云OAuth 2.0服務(wù)向Native應(yīng)用返回令牌。
Native應(yīng)用通過獲取的令牌向阿里云發(fā)起訪問API的請(qǐng)求。
說明由于令牌可以代表用戶身份,因此應(yīng)用可以訪問當(dāng)前用戶的資源。
Proof Key機(jī)制的原理
Native應(yīng)用支持Proof Key機(jī)制,用于每次獲取授權(quán)碼以及用授權(quán)碼換取訪問令牌。
這一機(jī)制可以減輕針對(duì)授權(quán)碼截獲的攻擊。
Native應(yīng)用生成:
code_verifier
,并保存好這個(gè)隨機(jī)字符串。說明code_verifier
是一個(gè)高熵值的隨機(jī)字符串,其取值為:[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
,長度限制為:43~128個(gè)字符。應(yīng)用根據(jù)
transform
的方式選擇生成code_challenge
。應(yīng)用在申請(qǐng)授權(quán)碼的同時(shí)提交: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編碼串,哈希算法的輸出字符串需要進(jìn)行BASE64-URL編碼。code_challenge
選擇方式計(jì)算示例:如果應(yīng)用采用方式為S256,生成
code_verifier
的值為dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk,那么code_challenge
為E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM。應(yīng)用獲取授權(quán)碼后,在使用授權(quán)碼換取訪問令牌時(shí),服務(wù)端通過計(jì)算判斷是否頒發(fā)令牌。
授權(quán)碼需包括
code_verifier
,服務(wù)端按照應(yīng)用選擇的transform
方式對(duì)code_verifier
進(jìn)行計(jì)算,將結(jié)果與code_challenge
進(jìn)行對(duì)比,如果一致則頒發(fā)訪問令牌。
獲取訪問令牌
Native應(yīng)用通過瀏覽器將用戶重定向到阿里云OAuth 2.0服務(wù)從而獲取授權(quán)碼。
授權(quán)碼的請(qǐng)求地址:
https://signin.aliyun.com/oauth2/v1/auth
。表 1. 請(qǐng)求參數(shù) 參數(shù)名稱
是否必選
描述
client_id
是
應(yīng)用的身份ID。
redirect_uri
是
創(chuàng)建應(yīng)用的重定向URI之一。
response_type
是
返回類型。根據(jù)OAuth 2.0協(xié)議,目前支持設(shè)置此參數(shù)的取值為code。
scope
否
空格分隔的OAuth范圍列表。如不指定此參數(shù)取值,則默認(rèn)為應(yīng)用的全部OAuth范圍。
state
否
應(yīng)用通過state參數(shù)實(shí)現(xiàn)多種目的,例如:狀態(tài)保持、作為nonce使用從而減少CSRF威脅等。state如果設(shè)置為任意字符串,阿里云OAuth 2.0服務(wù)會(huì)將請(qǐng)求中的state參數(shù)以及取值原樣放到返回參數(shù)中以供后續(xù)使用。
code_challenge_method
否
如果不指定此參數(shù),則默認(rèn)取值為plain。
code_challenge
否
根據(jù)客戶端指定的code_challenge_method,對(duì)隨機(jī)生成的code_verifier進(jìn)行轉(zhuǎn)換和編碼,轉(zhuǎn)換的結(jié)果作為code_challenge參數(shù)的值在授權(quán)碼請(qǐng)求中使用。
說明如果不指定此參數(shù),則無法使用Proof Key機(jī)制,在使用授權(quán)碼換取令牌時(shí)也不需要指定相應(yīng)的code_verifier,若授權(quán)碼被截獲可以直接被用于換取訪問令牌。
prompt
否
該參數(shù)用于指定服務(wù)器是否需要提示用戶進(jìn)行授權(quán)操作。
如果指定,會(huì)強(qiáng)制要求用戶進(jìn)行授權(quán),即使該阿里云賬號(hào)已經(jīng)做過授權(quán),也需要重新授權(quán)。如果不指定,則只在該阿里云賬號(hào)第一次使用該應(yīng)用時(shí)要求授權(quán)。
取值:
admin_consent
,表示服務(wù)端會(huì)在向客戶端返回信息之前展示授權(quán)頁面。請(qǐng)求示例
https://signin.aliyun.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應(yīng)用使用授權(quán)碼向阿里云OAuth 2.0服務(wù)申請(qǐng)代表用戶身份的令牌。
換取訪問令牌的請(qǐng)求地址:
https://oauth.aliyun.com/v1/token
。表 2. 請(qǐng)求參數(shù) 參數(shù)名稱
是否必選
描述
code
是
初始請(qǐng)求中獲取的授權(quán)碼。
client_id
是
應(yīng)用的身份ID。
redirect_uri
是
初始請(qǐng)求中設(shè)置的參數(shù)。
grant_type
是
根據(jù)OAuth 2.0協(xié)議, 取值為authorization_code。
code_verifier
否
初始請(qǐng)求中生成的code_verifier,對(duì)應(yīng)于授權(quán)碼請(qǐng)求中的code_challenge參數(shù)。
請(qǐng)求示例
POST /v1/token HTTP/1.1 Host: oauth.aliyun.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. 返回參數(shù) 參數(shù)名稱
描述
access_token
訪問令牌。訪問令牌可以代表用戶身份,應(yīng)用使用此訪問令牌來訪問阿里云API。應(yīng)用不需要理解訪問令牌的含義,直接使用即可。
expires_in
訪問令牌的剩余有效時(shí)間,單位為秒。
token_type
訪問令牌的類型。取值為Bearer。
id_token
身份令牌。id_token為OAuth簽名的JWT(JSON Web Token)。如果初始請(qǐng)求的scope參數(shù)包含了openid,則返回身份令牌。
refresh_token
刷新令牌。此參數(shù)可以直接使用,Native應(yīng)用不需要指定訪問令牌的值,可以直接獲得刷新令牌。
返回示例
{ "access_token": "eyJraWQiOiJrMTIzNCIsImVuYyI6****", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "Ccx63VVeTn2dxV7ovXXfLtAqLLERA****", "id_token": "eyJhbGciOiJIUzI1****" }
獲取新的訪問令牌
換取訪問令牌的請(qǐng)求地址:https://oauth.aliyun.com/v1/token
。
參數(shù)名稱 | 是否必選 | 描述 |
refresh_token | 是 | 用授權(quán)碼換取訪問令牌時(shí)獲得的刷新令牌。 |
client_id | 是 | 應(yīng)用的身份ID。 |
grant_type | 是 | 根據(jù)OAuth 2.0協(xié)議,取值為refresh_token。 |
請(qǐng)求示例
POST /v1/token HTTP/1.1
Host: oauth.aliyun.com
Content-Type: application/x-www-form-urlencoded
refresh_token=Ccx63VVeTn2dxV7ovXXfLtAqLLERAH****
client_id=98989****
grant_type=refresh_token
參數(shù)名稱 | 描述 |
access_token | 新的訪問令牌。應(yīng)用使用新的訪問令牌來訪問阿里云API。 |
expires_in | 訪問令牌的剩余有效時(shí)間,單位為秒。 |
token_type | 訪問令牌的類型。取值為Bearer。 |
返回示例
{
"access_token": "eyJraWQiOiJrMTIzNCIsImVuYyI6****",
"token_type": "Bearer",
"expires_in": 3600,
}
本次請(qǐng)求的返回值與用授權(quán)碼換取訪問令牌的返回值一致,但不包含refresh_token和id_token。
撤銷刷新令牌
Native應(yīng)用獲取了刷新令牌后,在用戶退出登錄應(yīng)用時(shí)或用戶將自己的賬號(hào)從應(yīng)用中移除時(shí),必須撤銷刷新令牌。
撤銷刷新令牌的請(qǐng)求地址:https://oauth.aliyun.com/v1/revoke
。
參數(shù)名稱 | 是否必選 | 描述 |
token | 是 | 需要撤銷的刷新令牌。 |
client_id | 是 | 應(yīng)用的身份ID。 |