Microsoft 身分識別平台和 OAuth 2.0 裝置授權授與流程
Microsoft 身分識別平台支援裝置授權授與,會允許使用者登入具有輸入限制的裝置,例如智慧型電視、物聯網裝置或印表機。 若要啟用此流程,裝置會讓使用者在其他裝置的瀏覽器中瀏覽網頁,以執行登入程序。 使用者登入後,裝置就能夠視需要取得存取權杖和重新整理權杖。
本文說明如何在您的應用程式中直接針對通訊協定進行程式設計。 建議您盡可能改為使用支援的 Microsoft 驗證程式庫 (MSAL),以取得權杖並呼叫受保護的 Web API。 您可參閱使用 MSAL 的範例應用程式以取得範例。
通訊協定圖表
下圖顯示了整個裝置程式碼流程。 在本文中說明了每個步驟。
裝置授權要求
用戶端必須先向驗證伺服器查詢用於初始化驗證的裝置和使用者代碼。 用戶端從 /devicecode
端點收集此要求。 在此要求中,用戶端也應一併附上必須向使用者索取的權限。
從傳送要求之後,使用者有 15 分鐘的時間可以登入。 這是 expires_in
的預設值。 只有在使用者指出已準備好登入時,才應提出此要求。
// Line breaks are for legibility only.
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/devicecode
Content-Type: application/x-www-form-urlencoded
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=user.read%20openid%20profile
參數 | 條件 | 描述 |
---|---|---|
tenant |
必要 | 可以是 /common 、/consumers 或 /organizations 。 這也可以是您想要以 GUID 或易記名稱格式對其要求權限的目錄租用戶。 |
client_id |
必要 | Microsoft Entra 系統管理中心 - 應用程式註冊體驗指派給您應用程式的應用程式 (用戶端) 識別碼。 |
scope |
必要 | 您要使用者同意的 範圍 空格分隔清單。 |
裝置授權回應
成功的回應是 JSON 物件,其中包含允許使用者登入的必要資訊。
參數 | 格式 | 描述 |
---|---|---|
device_code |
String | 用來在用戶端與授權伺服器之間驗證工作階段的長字串。 用戶端會使用此參數來向授權伺服器要求存取權杖。 |
user_code |
String | 向使用者顯示的短字串,用於識別輔助裝置上的工作階段。 |
verification_uri |
URI | 為了執行登入程序,使用者應使用 user_code 查看的 URI。 |
expires_in |
int | device_code 和 user_code 到期之前的秒數。 |
interval |
int | 在輪詢要求之間用戶端應等待的秒數。 |
message |
String | 人類看得懂的字串,其中包含使用者的指示。 在 ?mkt=xx-XX 形式的要求中加入 查詢參數、填寫適當的語言文化代碼,即可進行當地語系化。 |
注意
目前不包含或支援 verification_uri_complete
回應欄位。 之所以提到這一點,是因為如果您讀取標準,您會看到 verification_uri_complete
列為裝置程式碼流程標準的選擇性部分。
驗證使用者
用戶端收到 user_code
和 verification_uri
之後,系統會顯示值,並指示使用者透過其行動電話或電腦瀏覽器登入。
如果使用者使用個人帳戶 (以 /common
或 /consumers
) 進行驗證,系統會要求他們再次登入,以將驗證狀態傳輸到裝置。 這是因為裝置無法存取使用者的 Cookie。 系統會要求他們同意用戶端所要求的權限。 不過,這不適用於用於驗證的工作或學校帳戶。
使用者在 verification_uri
進行驗證時,用戶端應使用 device_code
輪詢 /token
端點,以取得要求的權杖。
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=00001111-aaaa-2222-bbbb-3333cccc4444&device_code=GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8...
參數 | 必要 | 描述 |
---|---|---|
tenant |
必要 | 在初始要求中使用的相同租用戶或租用戶別名。 |
grant_type |
必要 | 必須是 urn:ietf:params:oauth:grant-type:device_code |
client_id |
必要 | 必須符合初始要求中使用的 client_id 。 |
device_code |
必要 | 裝置授權要求傳回的 device_code 。 |
預期的錯誤
裝置程式碼流程是一種輪詢通訊協定,因此我們會預期在完成使用者驗證之前,必須先將錯誤提供給用戶端。
錯誤 | 描述 | 用戶端動作 |
---|---|---|
authorization_pending |
使用者尚未完成驗證,但未取消流程。 | 經過至少 interval 秒後,重複要求流程。 |
authorization_declined |
終端使用者拒絕了授權要求。 | 停止輪詢,並還原到未驗證的狀態。 |
bad_verification_code |
無法識別傳送至 /token 端點的 device_code 。 |
確認用戶端是否在要求中傳送正確的 device_code 。 |
expired_token |
已超過 expires_in 的最大值,而無法再使用 device_code 驗證。 |
停止輪詢,並還原到未驗證的狀態。 |
成功的驗證回應
成功的權杖回應如下所示:
{
"token_type": "Bearer",
"scope": "User.Read profile openid email",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..."
}
參數 | 格式 | 描述 |
---|---|---|
token_type |
String | 一律為 Bearer 。 |
scope |
空格分隔的字串 | 如果傳回了存取權杖,則會列出存取權杖的有效範圍。 |
expires_in |
int | 所含存取權杖的有效時間長度 (秒數)。 |
access_token |
不透明字串 | 針對已要求的範圍發出。 |
id_token |
JWT | 原始 scope 參數包含 openid 範圍時發出。 |
refresh_token |
不透明字串 | 原始 scope 參數包含 offline_access 時發出。 |
您可以使用 OAuth 程式碼流程文件中記載的相同流程,透過重新整理權杖來取得新的存取權杖和重新整理權杖。
警告
請勿在程式碼中,嘗試驗證或讀取任何您未擁有的 API 的權杖 (包括此範例中的權杖)。 Microsoft 服務的權杖可以使用不會驗證為 JWT 的特殊格式,且可能為取用者 (Microsoft 帳戶) 使用者進行加密。 雖然讀取權杖是很實用的偵錯與學習工具,但請勿在程式碼中依賴此功能的相依性,或是假設並非用於您所控制 API 的權杖相關內容。