共用方式為


Microsoft身分識別平臺和 OAuth 2.0 資源擁有者密碼認證

Microsoft身分識別平臺支援 OAuth 2.0 資源擁有者密碼認證 (ROPC) 授與,這可讓應用程式直接處理其密碼來登入使用者。 本文說明如何直接針對應用程式中的通訊協議進行程序設計。 可能的話,建議您改用支援的 Microsoft 驗證連結庫 (MSAL) 來 取得令牌,並呼叫受保護的 Web API。 另請參閱使用 MSAL 範例應用程式。

警告

Microsoft建議您不要 使用 ROPC 流程;它與多重要素驗證不相容(MFA)。 在大部分情況下,有更安全的替代方案可供使用,並建議使用。 此流程在應用程式中需要非常高的信任度,而且具有在其他流程中不存在的風險。 只有在更安全的流程無法運作時,才應該使用此流程。

重要

  • Microsoft 身分識別平臺僅支援 Microsoft Entra 租用戶內的 ROPC 授權,而不支援個人帳戶。 這表示您必須使用特定租戶的端點(https://login.microsoftonline.com/{TenantId_or_Name})或organizations端點。
  • 受邀加入 Microsoft Entra 租戶的個人帳戶無法使用 ROPC 流程。
  • 沒有密碼的帳戶無法使用 ROPC 登入,這表示 SMS 登入、FIDO 和 Authenticator 應用程式等功能將無法使用該流程。 如果您的應用程式或使用者需要這些功能,請使用 ROPC 以外的授與類型。
  • 如果使用者需要使用 多重要素驗證 (MFA) 來登入應用程式,則會被阻止登入。
  • 混合式身分識別同盟 情景不支援 ROPC(例如,Microsoft Entra ID 與 AD FS 用於驗證內部部署帳戶)。 如果使用者已將完整頁面重新導向至內部部署識別提供者,Microsoft Entra ID 無法針對該識別提供者測試使用者名稱和密碼。 不過,ROPC 支援 傳遞驗證
  • 混合式身分識別同盟案例的例外狀況如下:AllowCloudPasswordValidation 的主領域探索原則 設定為 TRUE,可讓 ROPC 流程在內部部署密碼同步至雲端時為同盟用戶運作。 如需詳細資訊,請參閱 針對舊版應用程式啟用同盟使用者的直接 ROPC 驗證
  • ROPC 流程不支援具有前置或尾端空格符的密碼。

如何從 ROPC 移轉

隨著 MFA 變得越來越普遍,某些Microsoft Web API 只有在已通過 MFA 需求時,才會接受存取令牌。 依賴 ROPC 的應用程式和測試環境將會被鎖定。Microsoft Entra 或不會發出令牌,或資源將拒絕要求。

如果您使用 ROPC 來取得令牌來呼叫受保護的下游 API,請移轉至安全的令牌取得策略。

使用者情境可用時

如果使用者需要存取資源,代表使用者的用戶端應用程式應該使用互動式驗證的形式。 只有當瀏覽器中出現提示時,終端使用者才可能被要求進行多因素驗證 (MFA)。

  • 針對 Web 應用程式:
  • Web API 無法顯示瀏覽器。 相反地,伺服器必須將挑戰訊息傳回給客戶端應用程式。 如需詳細資訊,請參閱 Web APIs在 Web APIs 中挑戰用戶的項目
  • 桌面應用程式應該使用代理式驗證。 經紀人使用基於瀏覽器的驗證,因此他們可以強制執行 MFA(多因素驗證),並啟用最安全的姿態。
  • 行動應用程式也應該設定為使用經紀人(Authenticator、公司入口)型驗證。

沒有用戶情境時

沒有涉及用戶內容的案例範例,但不限於下列案例:

  • 在 CI 流程中執行的腳本。
  • 服務需要代表本身呼叫資源,且沒有使用者詳細數據。

應用程式開發人員應該使用 服務主體驗證,如 精靈範例所示。 MFA 不適用於服務主體。

有多種方式可以驗證為服務主體:

  • 如果您的應用程式在 Azure 基礎結構上執行,請使用 受控識別。 受控識別可消除維護和輪替秘密和憑證的額外負荷。
  • 如果您的應用程式是在另一個 OAuth2 相容識別提供者所管理的系統上執行,例如 GitHub,請使用 同盟身分識別認證
  • 如果您無法使用受控識別或聯邦身份,請使用 憑證認證

警告

當使用者內容可用時,請勿使用服務主體帳戶驗證。 僅限應用程式的存取本質上具有高許可權,通常會授與整個租戶的存取權,並可能允許惡意行為者存取任何使用者的客戶的資料。

通訊協議圖表

下圖顯示 ROPC 流程。

顯示資源擁有者密碼認證流程的圖表

授權要求

ROPC 流程是單一要求;它會將客戶端識別和使用者的認證傳送至識別提供者,並接收傳回的令牌。 客戶端必須先要求使用者的電子郵件位址(UPN)和密碼,才能這麼做。 在成功請求之後,客戶端應該從記憶體中安全地刪除用戶的憑證。 它絕不能儲存它們。

// Line breaks and spaces are for legibility only.  This is a public client, so no secret is required.

POST {tenant}/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=user.read%20openid%20profile%20offline_access
&username=MyUsername@myTenant.com
&password=SuperS3cret
&grant_type=password
參數 條件 描述
tenant 必填 您要登入使用者的目錄租戶。 租戶識別可以是 GUID 格式或顯示名稱格式。 不過,其參數無法設定為 commonconsumers,但可能設定為 organizations
client_id 必填 Microsoft Entra 系統管理中心 - 應用程式註冊 頁面指派給您的應用程式(用戶端)識別碼。
grant_type 必填 必須設定為 password
username 必填 用戶的電子郵件位址。
password 必填 用戶的密碼。
scope 推薦 應用程式所需的 範圍或許可權的空間分隔清單。 在互動式流程中,系統管理員或用戶必須事先同意這些範圍。
client_secret 有時需要 如果您的應用程式是公用用戶端,則無法包含 client_secretclient_assertion。 如果應用程式是機密用戶端,則必須包含它。
client_assertion 有時需要 不同形式的client_secret,使用憑證產生。 如需詳細資訊,請參閱 憑證認證

成功的驗證回應

下列範例顯示成功的令牌回傳:

{
    "token_type": "Bearer",
    "scope": "User.Read profile openid email",
    "expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..."
}
參數 格式 描述
token_type 字串 永遠設定為 Bearer
scope 空格分隔字串 如果傳回存取令牌,此參數會列出存取令牌的有效範圍。
expires_in 整數 存取令牌的有效秒數。
access_token 不透明字串 針對所要求的 範圍發出
id_token JWT 如果原始 scope 參數包含 openid 範圍,則會發出。
refresh_token 不透明字串 如果原始 scope 參數包含 offline_access,則發出。

您可以使用重新整理權杖,通過文件 中所述的 OAuth 程式代碼流程取得新的存取權杖和重新整理權杖

警告

請勿在程式代碼中嘗試驗證或讀取您未擁有之任何 API 的令牌,包括此範例中的令牌。 Microsoft 服務的令牌可以使用一種不符合 JWT 驗證的特殊格式,並且還可以為消費者(使用微軟帳戶的用戶)進行加密。 雖然讀取令牌是實用的偵錯和學習工具,但請勿在程式碼中對其建立依賴性,也不要假設非您自身 API 所控制範圍的令牌具體細節。

錯誤回應

如果使用者未提供正確的使用者名稱或密碼,或用戶端尚未收到要求的同意,驗證將會失敗。

錯誤 描述 用戶端動作
invalid_grant 驗證失敗 認證不正確,或用戶端未同意要求的範圍。 如果未授予範圍,將會傳回 consent_required 錯誤。 若要解決此錯誤,客戶端應該使用網頁檢視或瀏覽器,將用戶傳送至互動式提示。
invalid_request 要求的構建不當 /common/consumers 驗證上下文不支援此授權類型。 請改用 /organizations 或租用戶標識碼。

瞭解更多資訊

如需 ROPC 流程的範例實作,請參閱 GitHub 上的 .NET 控制台應用程式 程式代碼範例。