Microsoft 身分識別平台 和 OAuth 2.0 裝置授權授與流程
Microsoft 身分識別平台 支援裝置授權授與,可讓使用者登入受輸入限制的裝置,例如智慧型手機電視、IoT 裝置或印表機。 若要啟用此流程,裝置會讓使用者在另一部裝置的瀏覽器中瀏覽網頁來登入。 使用者登入後,裝置就能夠視需要取得存取權杖和重新整理權杖。
本文說明如何直接針對應用程式中的通訊協議進行程序設計。 建議您盡可能改為使用支援的 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 | 和 user_code 到期之前的device_code 秒數。 |
interval |
int | 在輪詢要求之間用戶端應等待的秒數。 |
message |
String | 人類看得懂的字串,其中包含使用者的指示。 在表單?mkt=xx-XX 的要求中包含查詢參數,以填入適當的語言文化特性程式碼,即可進行當地語系化。 |
注意
verification_uri_complete
目前不包含或支持回應欄位。 我們提到這一點,因為如果您讀取標準,您會看到該verification_uri_complete
標準列為裝置程式代碼流程標準的選擇性部分。
驗證使用者
用戶端收到 user_code
和 verification_uri
之後,會顯示值,並指示使用者透過其行動或計算機瀏覽器登入。
如果使用者使用 或 /consumers
以個人帳戶進行驗證,/common
系統會要求他們再次登入,以便將驗證狀態傳輸至裝置。 這是因為裝置無法存取使用者的 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=535fb089-9ff3-47b6-9bfb-4f1264799865&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 |
device_code 無法辨識傳送至/token 端點的 。 |
確認用戶端正在要求中傳送正確的 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 的令牌相關細節。