Azure Active Directory B2C 中的 OAuth 2.0 授權碼流程

這很重要

自 2025 年 5 月 1 日起,Azure AD B2C 將不再可供新客戶購買。 在我們的常見問題中深入瞭解

您可以在裝置上安裝的應用程式中使用 OAuth 2.0 授權碼授與,以存取受保護的資源,例如 Web API。 藉由使用 OAuth 2.0 的 Azure Active Directory B2C (Azure AD B2C) 實作,您可以將註冊、登入和其他身分識別管理工作新增至單頁、行動裝置和桌面應用程式。 在本文中,我們會說明如何在不使用任何開放原始碼連結庫的情況下傳送和接收 HTTP 訊息。 本文與語言無關。 如果可能,建議您使用支援的 Microsoft 驗證庫(MSAL)。 看看 使用 MSAL 的範例應用程式

如需 OAuthh 2.0 授權碼流程的說明,請參閱 OAuth 2.0 規格的第 4.1 節。 您可以在大部分 的應用程式類型中使用它來進行驗證和授權,包括 Web 應用程式、單頁應用程式,以及原生安裝的應用程式。 您可以使用 OAuth 2.0 授權碼流程,安全地取得應用程式的存取令牌和重新整理令牌,這可用來存取 受授權伺服器保護的資源。 刷新令牌可讓用戶端在存取令牌到期後重新取得新的存取和刷新令牌,通常有效期為一小時。

本文著重於 公用用戶端 OAuth 2.0 授權碼流程。 公用用戶端是任何無法信任的用戶端應用程式,以安全地維護密碼的完整性。 這包括單頁應用程式、行動應用程式、傳統型應用程式,以及基本上未在伺服器上執行的任何應用程式。

備註

若要使用 Azure AD B2C 將身分識別管理新增至 Web 應用程式,請使用 OpenID Connect ,而不是 OAuth 2.0。

Azure AD B2C 擴充標準 OAuth 2.0 流程,以執行超越簡單驗證和授權的功能。 它引入使用者流程。 透過使用者流程,您可以使用 OAuth 2.0 將用戶體驗新增至您的應用程式,例如註冊、登入和配置檔管理。 使用 OAuth 2.0 通訊協議的識別提供者包括 AmazonMicrosoft Entra IDFacebookGitHubGoogleLinkedIn

若要嘗試本文中的 HTTP 要求:

  1. {tenant} 取代為您的 Azure AD B2C 租用戶名稱。
  2. 00001111-aaaa-2222-bbbb-3333cccc4444 替換為您先前在 Azure AD B2C 租用戶中註冊之應用程式的應用程式 ID。
  3. {policy} 替換為您在租用戶中建立的原則名稱,例如 b2c_1_sign_in

單頁應用程式需要設定重新導向 URI

單頁應用程式的授權碼流程需要一些額外的設定。 請依照建立單頁應用程式的指示,正確將您的重新導向 URI 標記為已啟用 CORS。 若要更新現有的重新導向 URI 以啟用 CORS,您可以在應用程式註冊的 [驗證] 索引標籤標的 [Web] 區段中按下移轉提示。或者,您可以開啟應用程式註冊指令清單編輯器,並在 區段中將重新導向 URI 的type欄位設定spareplyUrlsWithType

spa 重新導向類型與隱含流程向下相容。 目前使用隱含流程取得詞元的應用程式,可以無痛移轉到 spa 重新導向 URI 類型,並繼續使用隱含流程。

1.取得授權碼

授權碼流程始於用戶端將使用者導向 /authorize 端點。 這是流程的互動式部分,用戶會採取動作。 在此要求中,用戶端會在 參數中 scope 指出它需要從使用者取得的許可權。 下列範例(具有可讀性的換行符)示範如何取得授權碼。 如果您要測試此 GET HTTP 要求,請使用瀏覽器。

GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=code
&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob
&response_mode=query
&scope=00001111-aaaa-2222-bbbb-3333cccc4444%20offline_access%20https://{tenant-name}/{app-id-uri}/{scope}
&state=arbitrary_data_you_can_receive_in_the_response
&code_challenge=YTFjNjI1OWYzMzA3MTI4ZDY2Njg5M2RkNmVjNDE5YmEyZGRhOGYyM2IzNjdmZWFhMTQ1ODg3NDcxY2Nl
&code_challenge_method=S256
參數 是必要的嗎? 說明
租戶 為必填項目 您的 Azure AD B2C 租用戶名稱
{policy} 為必填項目 要執行的使用者流程。 請指定您在 Azure AD B2C 租戶中建立的使用者流程名稱。 例如:b2c_1_sign_inb2c_1_sign_upb2c_1_edit_profile
client_id (客戶識別碼) 為必填項目 Azure 入口網站中指派給您應用程式的應用程式 ID。
response_type(回應類型) 為必填項目 回應類型,且必須包含 code 才能使用授權碼流程。 如果您在回應類型中包含它,例如 code+id_token,您就可以收到 ID 權杖,此時範圍需要包含 openid
redirect_uri 為必填項目 您應用程式的重新導向 URI,驗證回應會由此傳送到您的應用程式並由您的應用程式接收。 它必須與您在入口網站中註冊的其中一個重新導向 URI 完全相符,但必須進行 URL 編碼。
範圍 為必填項目 以空格分隔的範圍清單。 openid 範圍表示允許登入使用者,並以 ID 權杖的形式取得使用者相關資料。 offline_access 範圍對於 Web 應用程式而言是選用的。 它表示您的應用程式需要 重新整理令牌 ,才能擴充資源的存取權。 用戶端識別碼表示發行的詞元預期供 Azure AD B2C 註冊的用戶端使用。 https://{tenant-name}/{app-id-uri}/{scope} 表示可存取受保護資源的權限,例如 Web API。 如需詳細資訊,請參閱 要求存取令牌
回應模式 建議使用 您用來將結果授權碼傳回應用程式的方法。 它可以是 queryform_postfragment
提示 可選 所需的用戶互動類型。 目前唯一有效的值為 login,這會強制使用者在該要求上輸入其認證。 單一登錄不會生效。
程式碼挑戰 建議 / 必要 用於透過授權碼交換的證明金鑰 (PKCE) 來保護授權碼授與。 如果包含 code_challenge_method,則此為必要參數。 您必須在應用程式中新增邏輯,以產生 code_verifiercode_challengecode_challengecode_verifier的Base64 URL編碼SHA256哈希。 您會將 儲存 code_verifier 在應用程式中以供稍後使用,並連同授權要求一起傳送 code_challenge 。 如需詳細資訊,請參閱 PKCE RFC。 這現在建議用於所有應用程式類型 - 原生應用程式、SPA 和機密用戶端,例如 Web 應用程式。
code_challenge_method 建議 / 必要 用來為 code_challenge 參數編碼 code_verifier 的方法。 此值為 SS256,但規格允許在用戶端無法支援 SHA256 時改用 plain

如果您排除 code_challenge_method,但仍包含 code_challenge,則會 code_challenge 假設 為純文本。 Microsoft身分識別平台同時支援 plainS256。 如需詳細資訊,請參閱 PKCE RFC。 必須這樣做才能使用授權碼流程的單頁應用程式
登入提示 可用來預先填入登入頁面的登入名稱欄位。 如需詳細資訊,請參閱 預先填入登入名稱
domain_hint 提供 Azure AD B2C 一個提示,指出應該使用哪個社交身份識別提供者進行登入。 如果包含有效的值,使用者就會直接前往識別提供者登入頁面。 如需詳細資訊,請參閱將登入重新導向至社交提供者
自定義參數 可與自訂原則搭配使用的自訂參數。 例如, 動態自定義頁面內容 URI索引鍵/值宣告解析程式
狀態 建議使用 要求中包含的值,可以是任何內容的字串,供您使用。 通常,會使用隨機產生的唯一值來防止跨網站偽造要求攻擊。 也會先使用狀態來編碼應用程式中的使用者狀態相關資訊,再進行驗證要求。 例如使用者所在的頁面,或正在執行的使用者流程。

這很重要

為了安全與隱私,請勿將網址或其他敏感資料直接放入狀態參數。 相反地,請使用與瀏覽器儲存中資料相對應的金鑰或識別碼,例如 localStorage 或 sessionStorage。 這種方式讓你的應用程式在認證後能安全地參考必要的資料。

此時會要求使用者完成使用者流程的工作流程。 這可能涉及使用者輸入其使用者名稱和密碼、使用社交帳號登入、註冊目錄或執行其他一些操作。 用戶動作取決於使用者流程的定義方式。

使用者完成使用者流程之後,Microsoft Entra ID 會將回應傳回至您的應用程式,使用您在 redirect_uri 中設定的值。 它會使用 參數中指定的 response_mode 方法。 與執行的使用者流程無關,每個用戶動作案例的回應完全相同。

使用 response_mode=query 的成功回應如下所示:

GET urn:ietf:wg:oauth:2.0:oob?
code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...        // the authorization_code, truncated
&state=arbitrary_data_you_can_receive_in_the_response                // the value provided in the request
參數 說明
字碼 應用程式所要求的授權碼。 應用程式可以使用授權碼來要求目標資源的存取令牌。 授權碼是短期的。 通常會在大約 10 分鐘後過期。
狀態 請參閱上一節表格中的完整描述。 如果要求中包含 state 參數,則回應中應該會出現相同的值。 應用程式應該確認 state 要求和回應中的值完全相同。

錯誤回應也可以傳送至重新導向 URI,讓應用程式可以適當地處理它們:

GET urn:ietf:wg:oauth:2.0:oob?
error=access_denied
&error_description=The+user+has+cancelled+entering+self-asserted+information
&state=arbitrary_data_you_can_receive_in_the_response
參數 說明
錯誤 錯誤碼字串,可用來分類所發生的錯誤類型。 您也可以使用字串來回應錯誤。
錯誤描述 可協助您識別驗證錯誤根本原因的特定錯誤訊息。
狀態 請參閱上表的完整描述。 如果要求中包含 state 參數,則回應中應該會出現相同的值。 應用程式應該確認 state 要求和回應中的值完全相同。

2.取得存取令牌

現在您已取得授權碼,您可以透過將 POST 要求傳送至 /token 端點,用 code 兌換目標資源的詞元。 在 Azure AD B2C 中,您可以藉由在要求中指定範圍,像平常一樣 要求其他 API 的存取令牌

依慣例,您也可以使用應用程式的用戶端識別碼作為要求的範圍,為應用程式自己的後端 Web API 要求存取權杖 (這會產生以該用戶端識別碼作為「對象」的存取權杖):

POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1

Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=00001111-aaaa-2222-bbbb-3333cccc4444 offline_access
&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...
&redirect_uri=urn:ietf:wg:oauth:2.0:oob
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong 
參數 是必要的嗎? 說明
租戶 為必填項目 您的 Azure AD B2C 租用戶名稱
{policy} 為必填項目 用來取得授權碼的使用者流程。 您無法在此要求中使用不同的使用者流程。
client_id (客戶識別碼) 為必填項目 Azure 入口網站中指派給您應用程式的應用程式 ID。
用戶端密鑰 是,在 Web Apps 中 Azure 入口網站中產生的應用程式密碼。 此流程會針對 Web 應用程式案例使用用戶端密碼,讓用戶端可以安全地儲存客戶端密碼。 針對原生應用程式(公用用戶端)案例,用戶端密碼無法安全地儲存,因此不會用於此呼叫。 如果您使用客戶端密碼,請定期變更它。
grant_type (授權類型) 為必填項目 授與的類型。 針對授權碼流程,授與類型必須是 authorization_code
範圍 建議使用 以空格分隔的範圍清單。 單一範圍值會向 Azure AD B2C 指出所要求的兩個許可權。 使用用戶端識別碼做為範圍,表示您的應用程式需要一個存取令牌,才能用於您自己的服務或Web API,以相同的用戶端識別元表示。 offline_access 範圍表示您的應用程式需要重新整理權杖,以便長時間存取資源。 您也可以使用 openid 範圍向 Azure AD B2C 要求 ID 令牌。
字碼 為必填項目 您從 /authorize 端點取得的授權碼。
redirect_uri 為必填項目 您接收授權碼的應用程式重新導向 URI。
code_verifier 建議使用 用來取得授權碼的相同 code_verifier。 如果在授權碼授與要求中使用 PKCE,則此為必要參數。 如需詳細資訊,請參閱 PKCE RFC

如果您要測試此 POST HTTP 要求,您可以使用任何 HTTP 用戶端,例如 Microsoft PowerShell

成功的權杖回應如下所示:

{
    "not_before": "1442340812",
    "token_type": "Bearer",
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "scope": "00001111-aaaa-2222-bbbb-3333cccc4444 offline_access",
    "expires_in": "3600",
    "refresh_token": "AAQfQmvuDy8WtUv-sd0TBwWVQs1rC-Lfxa_NDkLqpg50Cxp5Dxj0VPF1mx2Z...",
}
參數 說明
not_before 以 Epoch 時間表示該權杖開始視為有效的時間。
令牌類型 權杖類型值。 Microsoft Entra ID 唯一支援的類型是 Bearer。
access_token(存取憑證) 您所要求的已簽署 JSON Web 權杖 (JWT)。
範圍 令牌有效的範圍。 您也可以使用範圍快取詞元,以供稍後使用。
expires_in 令牌有效的時間長度(以秒為單位)。
refresh_token OAuth 2.0 重新整理權杖。 應用程式可以使用此令牌,在目前令牌到期后取得其他令牌。 重新整理權杖會長期存在。 您可以使用它們來保留資源長時間的存取權。 如需詳細資訊,請參閱 Azure AD B2C 令牌參考

錯誤回應如下所示:

{
    "error": "access_denied",
    "error_description": "The user revoked access to the app.",
}
參數 說明
錯誤 錯誤碼字串,可用來分類所發生的錯誤類型。 您也可以使用字串來回應錯誤。
錯誤描述 可協助您識別驗證錯誤根本原因的特定錯誤訊息。

3.使用令牌

既然您已成功取得存取令牌,您可以將令牌包含在標頭中 Authorization,以便在對後端 Web API 的請求中使用它。

GET /tasks
Host: mytaskwebapi.com
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...

4.重新整理令牌

存取令牌和標識碼令牌是短期的。 到期之後,您必須重新整理它們,才能繼續存取資源。 當您重新整理存取令牌時,Azure AD B2C 會傳回新的令牌。 重新整理後的存取權杖會更新 nbf (not before)、iat (issued at) 與 exp (expiration) 宣告值。 所有其他聲明值都與原始發行的存取令牌相同。

若要重新整理令牌,請將另一個 POST 要求提交至 /token 端點。 這次,請提供 refresh_token ,而不是 code

POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1

Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=00001111-aaaa-2222-bbbb-3333cccc4444 offline_access
&refresh_token=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...
&redirect_uri=urn:ietf:wg:oauth:2.0:oob
參數 是必要的嗎? 說明
租戶 為必填項目 您的 Azure AD B2C 租用戶名稱
{policy} 為必填項目 用來取得原始重新整理權杖的使用者流程。 您無法在此要求中使用不同的使用者流程。
client_id (客戶識別碼) 為必填項目 Azure 入口網站中指派給您應用程式的應用程式 ID。
用戶端密鑰 是,在 Web Apps 中 Azure 入口網站中產生的應用程式密碼。 此流程會針對 Web 應用程式案例使用用戶端密碼,讓用戶端可以安全地儲存客戶端密碼。 針對原生應用程式(公用用戶端)案例,用戶端密碼無法安全地儲存,因此不會用於此呼叫。 如果您使用客戶端密碼,請定期變更它。
grant_type (授權類型) 為必填項目 授與的類型。 對於授權碼流程的這個部分,授與類型必須是 refresh_token
範圍 建議使用 以空格分隔的範圍清單。 單一範圍值會向 Microsoft Entra ID 表示所要求的兩種權限。 使用用戶端識別碼做為範圍,表示您的應用程式需要一個存取令牌,才能用於您自己的服務或Web API,以相同的用戶端識別元表示。 offline_access 範圍表示您的應用程式需要重新整理權杖,以便長時間存取資源。 您也可以使用 openid 範圍向 Azure AD B2C 要求 ID 令牌。
redirect_uri 可選 您接收授權碼的應用程式重新導向 URI。
refresh_token 為必填項目 您在流程第二階段取得的原始重新整理權杖。

成功的權杖回應如下所示:

{
    "not_before": "1442340812",
    "token_type": "Bearer",
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "scope": "00001111-aaaa-2222-bbbb-3333cccc4444 offline_access",
    "expires_in": "3600",
    "refresh_token": "AAQfQmvuDy8WtUv-sd0TBwWVQs1rC-Lfxa_NDkLqpg50Cxp5Dxj0VPF1mx2Z...",
}
參數 說明
not_before 以 Epoch 時間表示該權杖開始視為有效的時間。
令牌類型 權杖類型值。 Microsoft Entra ID 唯一支援的類型是 Bearer。
access_token(存取憑證) 您所要求的已簽署 JWT。
範圍 令牌有效的範圍。 您也可以使用範圍來快取詞元,以供稍後使用。
expires_in 令牌有效的時間長度(以秒為單位)。
refresh_token OAuth 2.0 重新整理權杖。 應用程式可以使用此令牌,在目前令牌到期后取得其他令牌。 重新整理權杖是長效的,可用來在較長時間內保留對資源的存取權。 如需詳細資訊,請參閱 Azure AD B2C 令牌參考

錯誤回應如下所示:

{
    "error": "access_denied",
    "error_description": "The user revoked access to the app.",
}
參數 說明
錯誤 錯誤碼字串,可用來分類發生的錯誤類型。 您也可以使用字串來回應錯誤。
錯誤描述 可協助您識別驗證錯誤根本原因的特定錯誤訊息。

使用您自己的 Azure AD B2C 目錄

若要自行嘗試這些要求,請完成下列步驟。 以您自己的值取代本文中使用的範例值。

  1. 建立 Azure AD B2C 目錄。 在請求中使用目錄的名稱。
  2. 建立應用程式 以取得應用程式識別碼和重新導向 URI。 在您的應用程式中包含原生用戶端。
  3. 建立您的使用者流程 以取得您的使用者流程名稱。