Microsoft 身分識別平台上的 OpenID Connect

OpenID 連線 (OIDC) 會擴充 OAuth 2.0 授權通訊協定,以做為額外的驗證通訊協定。 您可以使用 OIDC,透過稱為標識元令牌的安全性令牌,在啟用 OAuth 的應用程式之間啟用單一登錄 (SSO)。

OIDC 的完整規格可在 OpenID Foundation 的網站上取得,網址為 OpenID 連線 Core 1.0 規格

通訊協定流程:登入

下圖顯示基本的 OpenID 連線 登入流程。 本文稍後章節將詳細說明流程中的步驟。

Swim-lane diagram showing the OpenID Connect protocol's sign-in flow.

啟用標識碼令牌

當用戶端應用程式在使用者驗證期間要求標識符時,OpenID 連線 引進的標識碼令牌是由授權伺服器 Microsoft 身分識別平台 所發出。 標識元令牌可讓用戶端應用程式驗證使用者的身分識別,並取得他們的其他資訊(宣告)。

針對向 Microsoft 身分識別平台 註冊的應用程式,預設不會發出標識元令牌。 應用程式的識別碼令牌是使用下列其中一種方法來啟用:

  1. 登入 Microsoft Entra 系統管理中心。
  2. 流覽至 [身分>識別應用程式> 應用程式註冊>< 您的應用程式>>驗證。
  3. 在 [平台設定] 底下,選取 [新增平台]
  4. 在開啟的窗格中,選取應用程式的適當平臺。 例如,針對 Web 應用程式選取 [Web ]。
  5. 在 [重新導向 URI] 下,新增應用程式的重新導向 URI。 例如: https://localhost:8080/
  6. [隱含授與和混合式流程] 下,選取 [ 用於隱含和混合式流程] 複選框。

或:

  1. 選取 [身分>識別應用程式> 應用程式註冊>< 您的應用程式>>指令清單。
  2. 在應用程式註冊的應用程式指令清單中設定oauth2AllowIdTokenImplicitFlowtrue

如果應用程式未啟用識別碼令牌,且要求標識元令牌,則 Microsoft 身分識別平台 會unsupported_response傳回類似下列的錯誤:

此客戶端不允許輸入參數 『response_type』 提供的值。 預期的值為 'code'.

藉由指定 response_typeid_token 來要求標識元令牌的說明, 請參閱本文稍後的傳送登入要求

擷取 OpenID 組態檔

openID 提供者,例如 Microsoft 身分識別平台 在可公開存取的端點上提供 OpenID 提供者組態檔,其中包含提供者的 OIDC 端點、支援的宣告和其他元數據。 用戶端應用程式可以使用元數據來探索用於驗證的URL,以及驗證服務的公開簽署密鑰。

驗證連結庫是 OpenID 組態檔的最常見取用者,用來探索驗證 URL、提供者的公開簽署密鑰和其他服務元數據。 如果您的應用程式中使用驗證連結庫,您可能不需要向 OpenID 組態檔端點遞交程式代碼要求和回應。

尋找應用程式的 OpenID 設定檔案 URI

Microsoft Entra ID 中的每個應用程式註冊都會提供可公開存取的端點,以提供其 OpenID 設定檔。 若要判斷應用程式組態檔端點的 URI,請將 已知的 OpenID 組態 路徑附加至應用程式註冊的 授權單位 URL

  • 已知的群組態檔路徑: /.well-known/openid-configuration
  • 授權單位 URL: https://login.microsoftonline.com/{tenant}/v2.0

的值 {tenant} 會根據應用程式的登入物件而有所不同,如下表所示。 授權單位 URL 也會因雲端實例而異

Description
common 具有個人 Microsoft 帳戶和公司或學校帳戶的使用者都可以從 Microsoft Entra ID 登入應用程式。
organizations 只有具有來自 Microsoft Entra ID 之公司或學校帳戶的使用者才能登入應用程式。
consumers 只有具有個人 Microsoft 帳戶的使用者才能登入應用程式。
8eaef023-2b34-4da1-9baa-8bc8c9d6a490contoso.onmicrosoft.com 只有來自特定 Microsoft Entra 租使用者的使用者(具有公司或學校帳戶的目錄成員或具有個人 Microsoft 帳戶的目錄來賓)才能登入應用程式。

此值可以是 Microsoft Entra 租使用者的功能變數名稱或 GUID 格式的租用戶識別碼。 您也可以使用取用者租使用者 GUID 來 9188040d-6c67-4c5b-b112-36a304b66dad取代 consumers

提示

請注意,針對個人 Microsoft 帳戶使用 commonconsumers 授權單位時,取用的資源應用程式必須設定為根據 signInAudience 支援這類帳戶類型。

若要在 Microsoft Entra 系統管理中心尋找 OIDC 設定檔,請登入 Microsoft Entra 系統管理中心 ,然後:

  1. 流覽至 [身分>識別應用程式> 應用程式註冊>< 您的應用程式>>端點。
  2. 找出 OpenID 底下的 URI 連線 元數據檔

範例要求

下列要求會從 common Azure 公用雲端上授權單位的 OpenID 設定檔端點取得 OpenID 組態元資料:

GET /common/v2.0/.well-known/openid-configuration
Host: login.microsoftonline.com

提示

試試看! 若要檢視應用程式授權單位的 OpenID 組 common 態檔,請瀏覽至 https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

範例回應

組態元數據會以 JSON 格式傳回,如下列範例所示(為了簡潔而截斷)。 JSON 回應中傳回的元數據會在 OpenID 連線 1.0 探索規格詳細說明。

{
  "authorization_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize",
  "token_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token",
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "private_key_jwt"
  ],
  "jwks_uri": "https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys",
  "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo",
  "subject_types_supported": [
      "pairwise"
  ],
  ...
}

傳送登入要求

若要驗證使用者並要求標識碼令牌以用於您的應用程式,請將其使用者代理程序導向至 Microsoft 身分識別平台 的 /authorize 端點。 要求類似於 OAuth 2.0 授權碼流程的第一回合,但有下列差異:

  • openid 參數中包含 scope 範圍。
  • 在參數中response_type指定 id_token
  • nonce包含參數。

範例登入要求(僅包含換行符以供可讀性):

GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=form_post
&scope=openid
&state=12345
&nonce=678910
參數 條件 描述
tenant 必要 您可以使用 {tenant} 要求路徑中的 值來控制誰可以登入應用程式。 允許的值為 commonorganizationsconsumers和租用戶標識碼。 如需詳細資訊,請參閱 通訊協定基本概念。 關鍵是,對於將使用者從某個租使用者登入另一個租使用者的來賓案例,您必須提供租使用者標識碼,才能正確地將使用者登入資源租使用者。
client_id 必要 Microsoft Entra 系統管理中心所指派的應用程式 (用戶端) 識別元– 應用程式註冊 指派給您的應用程式體驗。
response_type 必要 必須包含用於 OpenID Connect 登入的 id_token
redirect_uri 建議需求 應用程式的重新導向 URI,應用程式可以傳送和接收驗證回應。 它必須與您在入口網站中註冊的其中一個重新導向 URI 完全相符,不同之處在於它必須經過 URL 編碼。 如果沒有,端點會隨機挑選一個註冊 redirect_uri 的端點,以將用戶傳回。
scope 必要 以空格分隔的範圍清單。 若為 OpenID 連線,它必須包含範圍 openid,其會轉譯為同意 UI 中的登入許可權。 您也可以在此要求中包含其他範圍,以要求同意。
nonce 必要 您的應用程式在其標識碼令牌要求中產生的值並傳送。 相同的nonce值會包含在 Microsoft 身分識別平台 傳回給您應用程式的識別碼令牌中。 若要減輕令牌重新執行攻擊,您的應用程式應該確認 nonce 標識元令牌中的值與要求令牌時所傳送的值相同。 此值通常是唯一的隨機字串。
response_mode 建議需求 指定應該用來將產生的授權碼傳送回應用程式的方法。 可以是 form_postfragment。 針對 Web 應用程式,我們建議使用 response_mode=form_post,以確保將令牌最安全的傳輸至您的應用程式。
state 建議需求 一個包含在要求中而將一併在權杖回應中傳回的值。 其可以是任何您所需內容的字串。 隨機產生的唯一值通常用來 防止跨網站要求偽造攻擊。 狀態也可用來在驗證要求發生之前,在應用程式中編碼用戶狀態的相關信息,例如使用者開啟的頁面或檢視。
prompt 選擇性 表示必要的使用者互動類型。 目前login唯一有效的值為、 noneconsent、 和 select_account。 宣告 prompt=login 會強制使用者在該要求上輸入其認證,以否定單一登錄。 參數 prompt=none 是相反的,而且應該與 login_hint 配對,以指出哪些用戶必須登入。 這些參數可確保使用者完全不會顯示任何互動式提示。 如果無法透過單一登錄以無訊息方式完成要求,Microsoft 身分識別平台 會傳回錯誤。 原因不包含已登入的使用者、提示的使用者未登入,或已登入多個使用者,但未提供任何提示。 宣告 prompt=consent 會在使用者登入之後觸發 OAuth 同意對話方塊。 對話框會要求使用者將許可權授與應用程式。 最後, select_account 顯示使用者帳戶選取器,否定無訊息 SSO,但允許用戶挑選想要登入的帳戶,而不需要認證專案。 您無法同時使用 login_hintselect_account
login_hint 選擇性 如果您事先知道使用者名稱,您可以使用此參數預先填入使用者登入頁面的使用者名稱和電子郵件位址字段。 應用程式通常會在重新驗證期間使用此參數,在已從先前的登入擷取 login_hint選擇性宣告 之後。
domain_hint 選擇性 同盟目錄中用戶的領域。 這會略過使用者在登入頁面上進行的電子郵件式探索程式,以取得稍微簡化的用戶體驗。 對於透過AD FS等內部部署目錄同盟的租使用者,這通常會因為現有的登入會話而產生順暢的登入。

此時,系統會提示使用者輸入其認證並完成驗證。 Microsoft 身分識別平台 會確認使用者已同意查詢參數中所scope指出的許可權。 如果使用者尚未同意上述任何許可權,Microsoft 身分識別平台 會提示使用者同意所需的許可權。 您可以深入了解 許可權、同意和多租用戶應用程式

在使用者驗證並授與同意之後,Microsoft 身分識別平台 會使用 參數中指定的response_mode方法,在指定的重新導向 URI 傳回應用程式回應。

成功的回覆

當您使用 response_mode=form_post 時,成功的響應類似於:

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNB...&state=12345
參數 描述
id_token 應用程式所要求的標識碼令牌。 您可以使用 id_token 參數來驗證使用者的身分識別,並使用用戶開始會話。 如需標識元令牌及其內容的詳細資訊,請參閱標識碼 令牌參考
state 如果要求中包含 state 參數,則回應中應該會出現相同的值。 應用程式必須確認要求與回覆中的狀態值完全相同。

回覆錯誤

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

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

error=access_denied&error_description=the+user+canceled+the+authentication
參數 描述
error 錯誤碼字串,可用來分類發生的錯誤類型,以及回應錯誤。
error_description 特定錯誤訊息,可協助您識別驗證錯誤的根本原因。

授權端點錯誤的錯誤碼

下表描述可在錯誤回應的 參數中 error 傳回的錯誤碼:

錯誤碼 描述 用戶端動作
invalid_request 通訊協定錯誤,例如遺漏的必要參數。 修正並重新提交要求。 應用程式測試期間應該攔截到此開發錯誤。
unauthorized_client 用戶端應用程式無法要求授權碼。 當用戶端應用程式未在 Microsoft Entra 識別符中註冊,或未新增至使用者的 Microsoft Entra 租使用者時,就會發生此錯誤。 應用程式可以提示使用者提供安裝應用程式的指示,並將它新增至 Microsoft Entra ID。
access_denied 資源擁有者拒絕同意。 除非使用者同意,否則用戶端應用程式可以通知使用者無法繼續。
unsupported_response_type 授權伺服器不支援要求中的回應類型。 修正並重新提交要求。 應用程式測試期間應該攔截到此開發錯誤。
server_error 伺服器發生未預期的錯誤。 重試要求。 這些錯誤可能是暫時性狀況所造成。 用戶端應用程式可能會向使用者說明其回應因暫時性錯誤而延遲。
temporarily_unavailable 伺服器暫時太忙碌,無法處理要求。 重試要求。 用戶端應用程式可能會向使用者說明其回應因暫時性狀況而延遲。
invalid_resource 目標資源無效,因為它不存在、Microsoft Entra ID 找不到,或設定不正確。 此錯誤表示資源若存在,則尚未在租用戶中設定。 應用程式可以提示使用者提供安裝應用程式的指示,並將其新增至 Microsoft Entra ID。

驗證標識碼令牌

在應用程式中接收標識碼令牌可能不一定足以完整驗證使用者。 您可能也需要驗證標識元令牌的簽章,並根據您的應用程式需求驗證其宣告。 如同所有 OpenID 提供者,Microsoft 身分識別平台 的識別碼令牌都是使用公鑰密碼編譯簽署的 JSON Web 令牌(JWT)。

使用標識元令牌進行授權的 Web 應用程式和 Web API 必須加以驗證,因為這類應用程式可以存取數據。 不過,其他類型的應用程式可能無法受益於標識元令牌驗證。 例如,原生和單頁應用程式(SPA)很少受益於標識元令牌驗證,因為任何實體具有裝置或瀏覽器實體存取權的實體都可能會略過驗證。

權杖驗證略過的兩個範例如下:

  • 藉由修改裝置的網路流量來提供假令牌或金鑰
  • 偵錯應用程式並在程式執行期間逐步執行驗證邏輯。

如果您在應用程式中驗證標識元令牌,建議您 不要 手動執行此動作。 請改用令牌驗證連結庫來剖析和驗證令牌。 令牌驗證連結庫適用於大部分的開發語言、架構和平臺。

標識元令牌中要驗證的內容

除了驗證標識元令牌的簽章之外,您也應該驗證其數個宣告,如驗證標識元令牌中所述。 另請參閱 簽署金鑰變換的重要資訊。

其他數個驗證很常見,而且會因應用程式案例而有所不同,包括:

  • 確保使用者/組織已註冊應用程式。
  • 確保使用者擁有適當的授權/許可權
  • 確保已發生特定的驗證強度,例如 多重要素驗證

驗證標識元令牌之後,您就可以開始與用戶進行會話,並使用令牌宣告中的資訊進行應用程式個人化、顯示或儲存其數據。

通訊協議圖表:存取令牌取得

許多應用程式不僅需要登入使用者,而且需要代表使用者存取受保護的資源,例如 Web API。 此案例結合了 OpenID 連線 來取得標識符令牌,以驗證使用者和 OAuth 2.0,以取得受保護資源的存取令牌。

完整的 OpenID 連線 登入和令牌取得流程看起來類似下圖:

OpenID Connect protocol: Token acquisition

取得 UserInfo 端點的存取令牌

除了標識元令牌之外,OIDC UserInfo 端點也會提供已驗證用戶的資訊。

若要取得 OIDC UserInfo 端點的存取令牌,請修改登入要求,如下所示:

// Line breaks are for legibility only.

GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=535fb089-9ff3-47b6-9bfb-4f1264799865        // Your app registration's Application (client) ID
&response_type=id_token%20token                       // Requests both an ID token and access token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F       // Your application's redirect URI (URL-encoded)
&response_mode=form_post                              // 'form_post' or 'fragment'
&scope=openid+profile+email                           // 'openid' is required; 'profile' and 'email' provide information in the UserInfo endpoint as they do in an ID token. 
&state=12345                                          // Any value - provided by your app
&nonce=678910                                         // Any value - provided by your app

您可以使用授權碼流程、裝置程式碼流程重新整理令牌來取代 response_type=token 來取得應用程式的存取令牌。

成功令牌回應

使用 response_mode=form_post成功回應:

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
 access_token=eyJ0eXAiOiJKV1QiLCJub25jZSI6I....
 &token_type=Bearer
 &expires_in=3598
 &scope=email+openid+profile
 &id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI....
 &state=12345

響應參數表示不論用來取得這些參數的流程為何,都相同。

參數 描述
access_token 將用來呼叫 UserInfo 端點的令牌。
token_type 永遠是 “Bearer”
expires_in 存取令牌到期多久,以秒為單位。
scope 授與存取令牌的許可權。 因為 UserInfo 端點裝載在 Microsoft Graph 上,所以可以 scope 包含先前授與應用程式的其他端點(例如 , User.Read
id_token 應用程式所要求的標識碼令牌。 您可以使用識別碼令牌來驗證使用者的身分識別,並與用戶開始會話。 您可以在識別碼令牌參考中找到有關識別元令牌及其內容的詳細數據。
state 如果要求中包含 state 參數,則回應中應該會出現相同的值。 應用程式必須確認要求與回覆中的狀態值完全相同。

警告

請勿在程式代碼中嘗試驗證或讀取您未擁有之任何 API 的令牌,包括此範例中的令牌。 Microsoft 服務 的令牌可以使用不會驗證為 JWT 的特殊格式,也可以為取用者 (Microsoft 帳戶) 使用者加密。 雖然讀取令牌是實用的偵錯和學習工具,但請勿在程式代碼中對此採取相依性,或假設您控制之 API 的令牌相關細節。

回覆錯誤

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

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

error=access_denied&error_description=the+user+canceled+the+authentication
參數 描述
error 錯誤碼字串,可用來分類發生的錯誤類型,以及回應錯誤。
error_description 特定錯誤訊息,可協助您識別驗證錯誤的根本原因。

如需可能錯誤碼和建議客戶端回應的描述,請參閱 授權端點錯誤的錯誤碼。

當您擁有授權碼和識別碼令牌時,您可以代表使用者登入並取得存取令牌。 若要登入使用者,您必須驗證標識元令牌,如驗證令牌中所述。 若要取得存取令牌,請遵循 OAuth 程式代碼流程檔中所述的步驟。

呼叫 UserInfo 端點

檢閱 UserInfo 檔 ,以瞭解如何使用此令牌呼叫 UserInfo 端點。

傳送註銷要求

若要註銷使用者,請執行這兩項作業:

  • 將使用者的使用者代理程式重新導向至 Microsoft 身分識別平台的註銷 URI
  • 清除應用程式的 Cookie,或結束應用程式中的用戶作業階段。

如果您無法執行任一作業,使用者可能會保持已驗證狀態,且下次使用您的應用程式時,系統不會提示使用者登入。

將使用者代理程式重新導向至 ,end_session_endpoint如 OpenID 連線 組態檔中所示。 支援 end_session_endpoint HTTP GET 和 POST 要求。

GET https://login.microsoftonline.com/common/oauth2/v2.0/logout?
post_logout_redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
參數 條件 描述
post_logout_redirect_uri 建議需求 成功註銷之後,使用者重新導向至的URL。如果未包含 參數,用戶會顯示 Microsoft 身分識別平台 所產生的泛型訊息。 此 URL 必須符合應用程式註冊入口網站中為您的應用程式註冊的其中一個重新導向 URI。
logout_hint 選擇性 啟用註銷,而不提示用戶選取帳戶。 若要使用 logout_hint,請在用戶端應用程式中啟用 login_hint選擇性宣告 ,並使用選擇性宣告的值 login_hint 做為 logout_hint 參數。 請勿使用UPN或電話號碼作為參數的值 logout_hint

注意

成功註銷之後,作用中的會話將會設定為非使用中。 如果已註銷的使用者存在有效的主要重新整理令牌(PRT),並執行新的登入,SSO 將會中斷,而且使用者會看到提示與帳戶選擇器。 如果選取的選項是參考PRT的已連線帳戶,則登入會自動繼續,而不需要插入新的認證。

單一註銷

當您將使用者重新導向至 end_session_endpoint時,Microsoft 身分識別平台 會從瀏覽器清除使用者的會話。 不過,使用者可能仍會登入其他使用 Microsoft 帳戶進行驗證的應用程式。 若要讓這些應用程式同時將使用者註銷,Microsoft 身分識別平台 會將 HTTP GET 要求傳送給使用者目前登入之所有應用程式的已註冊LogoutUrl。 應用程式必須清除識別用戶並傳 200 回回應的任何會話,以回應此要求。 如果您要在應用程式中支援單一 LogoutUrl 登出,您必須在應用程式的程式碼中實作這類 。 您可以從應用程式註冊入口網站設定 LogoutUrl

下一步