Microsoft 身分識別平台上的 OpenID Connect
OpenID Connect (OIDC) 會擴充 OAuth 2.0 授權通訊協定,以作為另一個驗證通訊協定使用。 您可以使用 OIDC,透過稱為識別碼權杖的安全性權杖,在啟用 OAuth 的應用程式之間啟用單一登入 (SSO)。
如需 OIDC 的完整規格,請參閱 OpenID Foundation 網站上的 OpenID Connect Core 1.0 規格 (英文)。
通訊協定流程:登入
下圖顯示基本的 OpenID Connect 登入流程。 流程中的步驟會在本文稍後的章節中更詳細說明。
啟用識別碼權杖
OpenID Connect 引進的識別碼權杖是在用戶端應用程式於使用者驗證期間要求時,由授權伺服器 (Microsoft 身分識別平台) 所發行。 識別碼權杖可讓用戶端應用程式驗證使用者的身分,並取得其他相關資訊 (宣告)。
預設不會對向 Microsoft 身分識別平台註冊的應用程式發行識別碼權杖。 應用程式的識別碼權杖是使用下列其中一種方法來啟用:
- 登入 Microsoft Entra 系統管理中心。
- 瀏覽至 [身分識別]>[應用程式]>[應用程式註冊]>[您的應用程式]<>>[驗證]。
- 在 [平台設定] 底下,選取 [新增平台]。
- 在開啟的窗格中,選取應用程式的適當平台。 例如,針對 Web 應用程式選取 [Web]。
- 在 [重新導向 URI] 下,新增應用程式的重新導向 URI。 例如:
https://localhost:8080/
。 - 在 [Implicit grant and hybrid flows] \(隱含授與和混合式流程\) 下,選取 [ID tokens (used for implicit and hybrid flows)] \(識別碼權杖 (用於隱含和混合式流程)\) 核取方塊。
或:
- 選擇 [身分識別]>[應用程式]>[應用程式註冊]>[您的應用程式]<>>[資訊清單]。
- 在應用程式註冊的應用程式資訊清單中將
oauth2AllowIdTokenImplicitFlow
設定為true
。
如果未為您的應用程式啟用識別碼令牌,而且要求識別元令牌,Microsoft 身分識別平台 會unsupported_response
傳回類似下列的錯誤:
不允許此用戶端使用為輸入參數 'response_type' 提供的值。 預期的值為 'code'.
本文稍後的傳送登入要求將說明如何指定 id_token
的 response_type
來要求識別碼權杖。
擷取 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 帳戶的使用者可以登入應用程式。 |
Directory (tenant) ID 或 contoso.onmicrosoft.com |
只有來自特定 Microsoft Entra 租用戶的使用者 (具有公司或學校帳戶的目錄成員,或是具有個人 Microsoft 帳戶的目錄來賓) 才可以登入應用程式。 此值可以是 Microsoft Entra 租用戶的網域名稱或 GUID 格式的租用戶識別碼。 |
提示
請注意,針對個人 Microsoft 帳戶使用 common
或 consumers
授權單位時,取用的資源應用程式必須根據 signInAudience 設定為支援這類帳戶類型。
若要在 Microsoft Entra 系統管理中心尋找 OIDC 設定文件,請登入 Microsoft Entra 系統管理中心,然後:
- 瀏覽至 [身分識別]>[應用程式]>[應用程式註冊]>[您的應用程式]<>>[端點]。
- 在 [OpenID Connect 中繼資料文件] 下找到 URI。
範例要求
以下要求會從 Azure 公用雲端上 common
授權單位的 OpenID 設定文件端點取得 OpenID 設定中繼資料:
GET /common/v2.0/.well-known/openid-configuration
Host: login.microsoftonline.com
提示
試試看! 若要查看應用程式 common
授權單位的 OpenID 設定文件,請瀏覽至 https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration。
範例回覆
設定中繼資料會以 JSON 格式傳回,如下列範例所示 (為了簡潔表示已刪減)。 JSON 回應中傳回的中繼資料會在 OpenID Connect 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 授權碼流程的第一個階段,但有下列區別:
- 在
scope
參數中包含openid
範圍。 - 在參數
response_type
中指定id_token
。 - 包含
nonce
參數。
範例登入要求 (包含分行符號僅為方便閱讀):
GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=form_post
&scope=openid
&state=12345
&nonce=678910
參數 | Condition | 描述 |
---|---|---|
tenant |
必要 | 您可以要求路徑中使用 {tenant} 值來控制可登入應用程式的人員。 允許的值為 common 、organizations 、consumers 及租用戶識別碼。 如需詳細資訊,請參閱通訊協定基本概念。 嚴格來說,針對您會將使用者從一個租用戶登入另一個租用戶的來賓案例,您必須提供租用戶識別碼,才能正確地將其登入資源租用戶。 |
client_id |
必要 | Microsoft Entra 系統管理中心 - 應用程式註冊體驗指派給您應用程式的「應用程式 (用戶端) 識別碼」。 |
response_type |
必要 | 必須包含用於 OpenID Connect 登入的 id_token 。 |
redirect_uri |
建議需求 | 應用程式的重新導向 URI,您的應用程式可在此傳送及接收驗證回應。 它必須與您在入口網站中註冊的其中一個重新導向 URI 完全相符,不過必須是 URL 編碼格式。 如果沒有,端點會隨機挑選一個註冊 redirect_uri 的端點,以將用戶傳回。 |
scope |
必要 | 以空格分隔的範圍清單。 針對 OpenID Connect,即必須包含範圍 openid ,其會在同意 UI 中轉譯成「讓您登入」權限。 您也可以在此要求中包含其他範圍來要求同意。 |
nonce |
必要 | 應用程式在針對識別碼權杖的要求中產生並傳送的值。 Microsoft 身分識別平台傳回給應用程式的識別碼權杖中會包含相同的 nonce 值。 若要減輕權杖重新執行攻擊,您的應用程式應該驗證識別碼權杖中的 nonce 值與要求權杖時所傳送的值相同。 此值通常是唯一的隨機字串。 |
response_mode |
建議需求 | 指定將產生的授權碼傳回到應用程式所應該使用的方法。 可以是 form_post 或 fragment 。 針對 Web 應用程式,建議使用 response_mode=form_post ,以確保會以最安全的方式將權杖傳輸至您的應用程式。 |
state |
建議需求 | 要求中包含的值,也會隨權杖回應傳回。 其可以是任何您所需內容的字串。 通常會使用一個隨機產生的唯一值來防止跨站台偽造要求攻擊。 此狀態也用來在驗證要求出現之前,於應用程式中將使用者狀態的相關資訊 (例如使用者所在的網頁或檢視) 編碼。 |
prompt |
選擇性 | 表示必要的使用者互動類型。 此時唯有 login 、none 、consent 及 select_account 是有效值。 prompt=login 宣告會強制使用者在該要求上輸入其認證,亦即取消單一登入。 prompt=none 參數是相反的,且應與搭配使用 login_hint ,以指出必須登入的使用者。 這些參數會確保無論如何都不會對使用者顯示任何互動式提示。 如果無法透過單一登入以無訊息方式完成要求,Microsoft 身分識別平台就會傳回錯誤。 原因包含沒有已登入的使用者、提示的使用者未登入,或已登入多個使用者但未提供提示。 prompt=consent 宣告會在使用者登入之後觸發 OAuth 同意對話方塊。 該對話方塊會請使用者將權限授與應用程式。 最後, select_account 顯示使用者帳戶選取器,否定單一註銷,但允許用戶挑選想要登入的帳戶,而不需要認證專案。 您無法同時使用 login_hint 和 select_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 ID 中註冊,或未新增至使用者的 Microsoft Entra 租用戶時。 應用程式可以對使用者提示一些指示,來安裝應用程式並將它新增到 Microsoft Entra ID。 |
access_denied |
資源擁有者拒絕同意。 | 用戶端應用程式可以通知使用者除非使用者同意,否則其無法繼續進行。 |
unsupported_response_type |
授權伺服器不支援要求中的回應類型。 | 修正並重新提交要求。 在應用程式測試期間,應該會攔截到此開發錯誤。 |
server_error |
伺服器發生非預期的錯誤。 | 重試要求。 這些錯誤可能是由暫時性狀況所引起。 用戶端應用程式可能會向使用者解釋其回應因暫時性錯誤而延遲。 |
temporarily_unavailable |
伺服器暫時過於忙碌而無法處理要求。 | 重試要求。 用戶端應用程式可能會向使用者解釋其回應因暫時性狀況而延遲。 |
invalid_resource |
目標資源因不存在、Microsoft Entra ID 找不到或設定不正確而無效。 | 此錯誤表示尚未在租用戶中設定資源 (如果存在)。 應用程式可以對使用者提示關於安裝應用程式並其新增至 Microsoft Entra ID 的指示。 |
驗證識別碼權杖
在您的應用程式中接收識別碼權杖可能不一定足以充分驗證使用者。 您可能需要一併驗證識別碼權杖的簽章,並依照您應用程式的需求確認其宣告。 類似所有 OIDC 提供者,Microsoft 身分識別平台的識別碼權杖是使用使用公開金鑰加密簽署的 JSON Web 權杖 (JWT)。
使用識別碼權杖進行授權的 Web 應用程式和 Web API 必須進行驗證,因為這類應用程式會限制資料存取。 不過,其他類型的應用程式可能無法受益於識別碼權杖驗證。 例如,原生和單頁應用程式(SPA)很少受益於標識元令牌驗證,因為任何實體具有裝置或瀏覽器實體存取權的實體都可能會略過驗證。
權杖驗證略過的兩個範例包括:
- 藉由修改裝置的網路流量來提供假權杖或金鑰
- 在程式執行期間偵錯應用程式並略過驗證邏輯。
如果您在應用程式中驗證識別碼權杖,建議「不要」手動執行此動作。 請改用權杖驗證程式庫來剖析和驗證權杖。 權杖驗證程式庫適用於大部分的開發語言、架構和平台。
在識別碼權杖中驗證的內容
除了驗證識別碼權杖的簽章之外,您也應該驗證其中幾個宣告,如驗證識別碼權杖中所述。 另請參閱簽署金鑰變換的相關重要資訊。
還有其他幾個驗證很常見,並會因應用程式案例而異,包括:
- 確保使用者/組織已註冊應用程式。
- 確保使用者擁有正確的授權/權限
- 確保所發生的驗證具有特定強度,例如多重要素驗證。
驗證識別碼權杖之後,您就可以開始使用者工作階段,並使用權杖宣告中的資訊進行應用程式個人化、顯示或儲存其資料。
通訊協定圖表:取得存取權杖
許多 Web 應用程式不僅需要將使用者登入,也需要代表使用者存取受保護的資源 (例如 Web API)。 此案例結合了 OpenID Connect 與 OAuth 2.0,前者可取得識別碼權杖以驗證使用者,後者可取得受保護資源的存取權杖。
完整的 OpenID Connect 登入和權杖取得流程看起來類似下圖:
取得使用者資訊端點的存取權杖
除了識別碼權杖之外,OIDC 使用者資訊端點也會提供已驗證的使用者資訊。
若要取得 OIDC 使用者資訊端點的存取權杖,請修改登入要求,如下所述:
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444 // 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 |
一律是「持有人」 |
expires_in |
存取權杖到期之前的時間長度 (以秒為單位)。 |
scope |
授與存取權杖的權限。 由於使用者資訊端點裝載於 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 文件,了解如何使用此權杖來呼叫使用者資訊端點。
傳送登出要求
若要註銷使用者,請執行下列兩項作業:
- 將使用者的使用者代理程式重新導向至 Microsoft 身分識別平台的登出 URI。
- 清除應用程式的 Cookie,或在您的應用程式中結束使用者的工作階段。
如果您無法執行這些作業,使用者可能會保持已驗證狀態,而且在下次使用應用程式時將不會收到登入提示。
將使用者代理程式重新導向至 end_session_endpoint
,如 OpenID Connect 設定文件中所示。 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
參數 | Condition | 描述 |
---|---|---|
post_logout_redirect_uri |
建議需求 | 使用者在成功登出之後,要重新導致到的 URL。若未包含此參數,則使用者會看到由 Microsoft 身分識別平台所產生的一般訊息。 此 URL 必須與您在應用程式註冊入口網站中為應用程式註冊的其中一個重新導向 URI 相符。 |
logout_hint |
選擇性 | 讓登出進行,而不提示使用者選取帳戶。 若要使用 logout_hint ,請在用戶端應用程式中啟用login_hint 選擇性宣告,並使用選擇性宣告的值login_hint 做為 logout_hint 參數。 請勿使用 UPN 或電話號碼作為 logout_hint 參數的值。 |
注意
成功登出之後,作用中的會話將會設定為非使用中。 如果已註銷使用者存在有效的主要重新整理令牌(PRT),並執行新的登入,則會中斷單一註銷,而且使用者會看到帳戶選擇器提示。 如果選取的選項是參考 PRT 的已連線帳戶,則登入會自動繼續,而不需要插入新的認證。
單一登出
當您將使用者重新導向至end_session_endpoint
應用程式中的 時,Microsoft 身分識別平台 結束此應用程式的用戶會話。 不過,使用者可能仍會登入使用相同Microsoft帳戶進行驗證的其他應用程式。
當使用者登入此目錄中註冊的多個 Web 或 SPA 應用程式時,單一登錄可讓此使用者立即註銷所有應用程式,方法是註銷其中一個應用程式。
若要為 Entra 應用程式啟用單一註銷,您應該使用 OpenID Connect 前端通道註銷功能。 此功能可讓應用程式通知其他應用程式使用者已註銷。當使用者註銷一個應用程式時,Microsoft 身分識別平台 會將 HTTP GET 要求傳送至使用者目前登入之每個應用程式的前端通道註銷 URL。
這些應用程式必須藉由執行下列兩個動作來回應此要求,單一註銷才能成功:
- 清除識別使用者的任何會話。
- 應用程式必須藉由清除任何可識別使用者的工作階段並傳回
200
回應,以回應此要求。
什麼是前端通道登出 URL?
前端通道註銷 URL 是您 Web 或 SPA 應用程式從 Entra 驗證伺服器接收註銷要求的位置,並執行單一登出功能。 每個應用程式都有一個前端通道登出 URL。
何時應該設定前端通道登出 URL?
如果您或開發人員已判斷應用程式需要單一註銷,則必須設定此應用程式應用程式註冊的前端通道註銷 URL。 設定此應用程式應用程式註冊的前端通道註銷 URL 之後,Microsoft 身分識別平台 會在登入的使用者登出另一個應用程式時,將 HTTP GET 要求傳送至此應用程式的前端通道註銷 URL。
如何使用前端通道註銷功能設定單一註銷
若要針對一組應用程式使用前端通道註銷功能,您必須完成下列兩項工作:
- 針對應同時註銷的所有應用程式,在 Microsoft Entra 系統管理中心設定前端通道註銷 URL。 每個應用程式通常都有自己的專用前端通道註銷 URL。
- 編輯應用程式程式代碼,以便他們接聽由 Microsoft 身分識別平台 傳送至前端通道註銷 URL 的 HTTP GET 要求,並清除識別使用者並傳回 200 回應的任何會話來回應此要求。
如何選擇前端通道註銷 URL
前端通道註銷 URL 應該是能夠接收和回應 HTTP GET 要求的 URL,而且應該能夠清除識別使用者的任何會話。 前端通道註銷 URL 的範例可能包括但不限於下列專案:
下一步
- 檢閱使用者資訊端點文件。
- 使用內部部署系統中的值填入權杖中的宣告值。
- 在權杖中包含您自己的宣告。