Microsoft 身分識別平台和OpenID Connect 通訊協定
文章推薦指數: 80 %
使用OpenID Connect 驗證通訊協定的Microsoft 身分識別平台實作來建置Web 應用 ... by your app &nonce=678910 // Any value, provided by your app.
跳到主要內容
已不再支援此瀏覽器。
請升級至MicrosoftEdge,以利用最新功能、安全性更新和技術支援。
下載MicrosoftEdge
其他資訊
目錄
結束焦點模式
閱讀英文
儲存
目錄
閱讀英文
儲存
Twitter
LinkedIn
Facebook
電子郵件
WeChat
目錄
Microsoft身分識別平台和OpenIDConnect通訊協定
發行項
06/13/2022
17位參與者
本文內容
OpenIDConnect(OIDC)是以OAuth2.0為基礎所建置的驗證通訊協定,可用來讓使用者安全地登入應用程式。
當您使用Microsoft身分識別平台的OpenIDConnect實作時,可以在應用程式中新增登入和API存取。
本文說明如何不受語言限制地執行此工作,並說明如何在不使用任何Microsoft開放原始碼程式庫的情況下,傳送和接收HTTP訊息。
OpenIDConnect將OAuth2.0「授權」通訊協定延伸來當作「驗證」通訊協定使用,以便讓您能夠使用OAuth來執行單一登入。
OpenIDConnect引進了「識別碼權杖」的概念,這是一種安全性權杖,可讓用戶端驗證使用者的身分識別。
識別碼權杖也會取得使用者的相關基本設定檔資訊。
同時也引進了使用者類型端點,這個API會傳回使用者的相關資訊。
提示
嘗試在Postman中執行此要求及其他操作--別忘了取代權杖與識別碼!
通訊協定圖表:登入
最基本的登入流程包含下圖中顯示的步驟。
本文有每個步驟的詳細說明。
擷取OpenIDConnect中繼資料文件
OpenIDConnect所描述的中繼資料文件(RFC)包含應用程式進行登入所需的大部分資訊。
這包括要使用的URL、服務的公開簽署金鑰位置等資訊。
您可以藉由將探索文件路徑附加至授權單位URL,來尋找這份文件:
探索文件路徑:/.well-known/openid-configuration
授權單位:https://login.microsoftonline.com/{tenant}/v2.0
{tenant}可以接受下列四個值的其中一個:
值
描述
common
使用者如果同時具有個人Microsoft帳戶和來自AzureAD的公司或學校帳戶,便可登入應用程式。
organizations
只有具有來自AzureAD之工作或學校帳戶的使用者可以登入應用程式。
consumers
只有具有個人Microsoft帳戶的使用者可以登入應用程式。
8eaef023-2b34-4da1-9baa-8bc8c9d6a490或contoso.onmicrosoft.com
只有來自特定AzureAD租用戶的使用者(無論他們具有公司或學校帳戶的目錄成員,還是具有個人Microsoft帳戶的目錄來賓)才可以登入應用程式。
可以使用AzureAD租用戶的易記網域名稱,或是租用戶的GUID識別碼。
您也可以使用取用者租用戶9188040d-6c67-4c5b-b112-36a304b66dad,來取代consumers租用戶。
授權單位會因國家雲端而異,例如https://login.microsoftonline.deAzureAD德國執行個體。
如果您未使用公用雲端,請檢查全國雲端端點,以找出適合您的國家/地區。
確定租用戶和/v2.0/出現在您的要求中,以便您可以使用端點的v2.0版本。
提示
試試看!按一下https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration以查看common設定。
範例要求
若要呼叫公用雲端上一般授權單位的使用者資訊端點,請使用下列方法:
GET/common/v2.0/.well-known/openid-configuration
Host:login.microsoftonline.com
範例回應
中繼資料是簡單的「JavaScript物件標記法」(JSON)文件。
如需範例,請參閱下列程式碼片段。
OpenIDConnect規格中有其內容的完整說明。
{
"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"
],
...
}
如果您的應用程式因使用claims-mapping功能而具有自訂簽署金鑰,您必須附加包含應用程式識別碼的appid查詢參數,以取得指向您應用程式簽署金鑰資訊的jwks_uri。
例如:https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?appid=6731de76-14a6-49ae-97bc-6eba6914391e包含內容為https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys?appid=6731de76-14a6-49ae-97bc-6eba6914391e的jwks_uri。
一般而言,您可使用此中繼資料文件來設定OpenIDConnect程式庫或SDK;程式庫會使用中繼資料來執行其工作。
不過,如果您並非使用預先建置的OpenIDConnect程式庫,則可遵循此文章其餘部分中的步驟,來使用Microsoft身分識別平台在Web應用程式中進行登入。
傳送登入要求
當您的Web應用程式需要驗證使用者時,其可以將使用者導向至/authorize端點。
這個要求類似於OAuth2.0授權碼流程的第一個階段,但有下列重要區別:
要求必須在scope參數中包含openid範圍。
response_type參數必須包含id_token。
要求必須包含nonce參數。
重要
若要成功向/authorization端點要求識別碼權杖,註冊入口網站中的應用程式註冊必須在[授權]索引標籤中啟用id_tokens的隱含授與(其會將應用程式資訊清單中的oauth2AllowIdTokenImplicitFlow旗標設定為true)。
如果未啟用,會傳回unsupported_response錯誤:"Theprovidedvaluefortheinputparameter'response_type'isnotallowedforthisclient.Expectedvalueis'code'"(此用戶端的'response_type'輸入參數不允許使用所提供的值。
預期的值為'code')
例如:
//Linebreaksareforlegibilityonly.
GEThttps://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=form_post
&scope=openid
&state=12345
&nonce=678910
參數
條件
描述
tenant
必要
您可以要求路徑中使用{tenant}值來控制可登入應用程式的人員。
允許的值為common、organizations、consumers及租用戶識別碼。
如需詳細資訊,請參閱通訊協定基本概念。
嚴格來說,針對您會將使用者從一個租用戶登入另一個租用戶的來賓案例,您必須提供租用戶識別碼,才能正確地將其登入資源租用戶。
client_id
必要
Azure入口網站-應用程式註冊體驗指派給您應用程式的應用程式(用戶端)識別碼。
response_type
必要
必須包含OpenIDConnect登入的id_token。
它也可能包含其他response_type值,例如code。
redirect_uri
建議
應用程式的重新導向URI,您的應用程式可在此傳送及接收驗證回應。
它必須與您在入口網站中註冊的其中一個重新導向URI完全相符,不過必須是URL編碼格式。
如果不存在,端點將會隨機挑選一個已註冊的redirect_uri來將使用者傳送回去。
scope
必要
範圍的空格分隔清單。
針對OpenIDConnect,即必須包含範圍openid,其會在同意UI中轉譯成「讓您登入」權限。
您也可以在此要求中包含其他範圍來要求同意。
nonce
必要
一個由應用程式產生且包含在要求中的值,此值會以宣告方式包含在產生的id_token中。
應用程式可以確認此值來減輕權杖重新執行攻擊的影響。
此值通常是一個隨機的唯一字串,可用來識別要求的來源。
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會向使用者顯示帳戶選取器,否定無訊息SSO,但允許使用者選擇他們想要登入的帳戶,而不需要認證輸入。
您無法一起使用login_hint和select_account。
login_hint
選用
如果您事先知道使用者名稱,便可使用此參數為使用者預先填入登入頁面的使用者名稱和電子郵件地址欄位。
通常應用程式會在重新驗證期間,在已從稍早的登入擷取login_hint選擇性宣告之後使用此參數。
domain_hint
選用
使用者於同盟目錄中的領域。
這會略過使用者在登入頁面上經歷的電子郵件型探索程序,以提供稍微更流暢的使用者體驗。
針對透過如ADFS的內部部署目錄進行同盟的租用戶,這通常會因現有的登入工作階段而導致流暢的登入。
此時,系統會要求使用者輸入其認證並完成驗證。
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參數來驗證使用者的身分識別,並開始與使用者的工作階段。
如需識別碼權杖及其內容的詳細資料,請參閱id_tokens參考。
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
用戶端應用程式無法要求授權碼。
這通常會在用戶端應用程式未在AzureAD中註冊,或未加入至使用者的AzureAD租用戶時發生。
應用程式可以對使用者提示一些指示,來安裝應用程式並將它新增到AzureAD。
access_denied
資源擁有者拒絕同意。
用戶端應用程式可以通知使用者除非使用者同意,否則其無法繼續進行。
unsupported_response_type
授權伺服器不支援要求中的回應類型。
修正並重新提交要求。
這是通常在初始測試期間擷取到的開發錯誤。
server_error
伺服器發生非預期的錯誤。
重試要求。
這些錯誤可能是由暫時性狀況所引起。
用戶端應用程式可能會向使用者解釋其回應因暫時性錯誤而延遲。
temporarily_unavailable
伺服器暫時過於忙碌而無法處理要求。
重試要求。
用戶端應用程式可能會向使用者解釋其回應因暫時性狀況而延遲。
invalid_resource
目標資源無效,因為其不存在、AzureAD找不到,或是其並未正確設定。
這表示在資源存在的情況下,尚未在租用戶中加以設定。
應用程式可以對使用者提示一些指示,來安裝應用程式並將它新增到AzureAD。
驗證識別碼權杖
僅接收id_token並不足以驗證使用者;您也需要驗證id_token簽章,並依照應用程式的需求確認權杖中的宣告。
類似所有OIDC平台,Microsoft身分識別平台會使用JSONWeb權杖(JWT)和公開金鑰加密來簽署識別碼權杖及驗證其是否有效。
並非所有應用程式都能受益於驗證識別碼權杖-原生應用程式和單一頁面應用程式,也就是說,較少受益於驗證識別碼權杖。
具有裝置(或瀏覽器)之實體存取權的人員,可以略過驗證,方法是將網路流量編輯至裝置,以提供假的權杖和金鑰,只是要將應用程式進行偵錯以略過驗證邏輯。
另一方面,使用識別碼權杖進行授權的Web應用程式和API必須謹慎地驗證識別碼權杖,因為其會控制資料的存取權。
在您驗證id_token的簽章之後,會有數個宣告需要驗證。
如需詳細資訊,請參閱id_token參考,其中包括驗證權杖和有關簽署金鑰變換的重要資訊。
我們建議利用程式庫來剖析和驗證權杖-對於大部分語言和平台至少有一個可用。
您可能也希望根據自己的案例驗證其他宣告。
一些常見的驗證包括:
確保使用者/組織已註冊應用程式。
確保使用者擁有正確的授權/權限
確保所發生的驗證具有特定強度,例如多重要素驗證。
在您驗證id_token之後,就可以與使用者開始工作階段,並使用id_token中的宣告來取得應用程式中的使用者相關資訊。
這項資訊可以用於顯示、記錄、個人化等等。
通訊協定圖表:存取權杖取得
許多Web應用程式不僅需要將使用者登入,也需要使用OAuth來代表使用者存取Web服務。
這個案例結合了OpenIDConnect來進行使用者驗證,同時又取得您使用OAuth授權碼流程時,可用來取得存取權杖的授權碼。
完整的OpenIDConnect登入和權杖取得流程看起來如下圖。
我們會在本文後續的小節中詳細說明每個步驟。
取得存取權杖以呼叫UserInfo
若要取得OIDC使用者資訊端點的權杖,請修改登入要求:
//Linebreaksareforlegibilityonly.
GEThttps://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e//YourregisteredApplicationID
&response_type=id_token%20token//thiswillreturnbothanid_tokenandanaccesstoken
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F//YourregisteredredirectURI,URLencoded
&response_mode=form_post//'form_post'or'fragment'
&scope=openid+profile+email//`openid`isrequired.`profile`and`email`provideadditionalinformationintheUserInfoendpointthesamewaytheydoinanIDtoken.
&state=12345//Anyvalue,providedbyyourapp
&nonce=678910//Anyvalue,providedbyyourapp
您也可以使用授權碼流程、裝置程式碼流程或重新整理權杖取代response_type=token來取得應用程式的權杖。
提示
請按一下以下連結來執行此要求。
登入之後,您的瀏覽器將會重新導向至https://localhost/myapp/,且網址列中會有識別碼權杖和權杖。
請注意,此要求僅供使用response_mode=fragment示範之用-針對webapp,我們建議您盡可能使用form_post,以提供額外的安全性。
https://login.microsoftonline.com/common/oauth2/v2.0/authorize...
成功的權杖回應
使用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
無論用來取得的流程為何,回應參數都代表相同的內容。
參數
Description
access_token
將用來呼叫使用者資訊端點的權杖。
token_type
一律是「持有人」
expires_in
存取權杖到期之前的時間長度(以秒為單位)。
scope
授與存取權杖的權限。
請注意,由於使用者資訊端點裝載於MSGraph,如果先前已將其授與應用程式,此處可能會列出其他的Graph範圍(例如user.read)。
這是因為指定資源的權杖一律包含目前授與用戶端的每個權限。
id_token
應用程式所要求的識別碼權杖。
您可以使用識別碼權杖來驗證使用者的身分識別,然後開始與使用者的工作階段。
如需有關識別碼權杖及其內容的更多詳細資料,請參閱id_tokens參考。
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文件,了解如何使用此權杖來呼叫使用者資訊端點。
傳送登出要求
當您想要將使用者登出應用程式時,只是清除應用程式的Cookie或結束使用者的工作階段還是不夠。
您也必須將使用者重新導向至Microsoft身分識別平台才能登出。
如果不這樣做,使用者不需要再次輸入認證就能重新向應用程式進行驗證,因為他們與Microsoft身分識別平台端點之間仍然存在有效的單一登入工作階段。
您可以將使用者重新導向至列在OpenIDConnect中繼資料文件內的end_session_endpoint(支援HTTPGET和POST要求):
GEThttps://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參數的值。
單一登出
當您將使用者重新導向至end_session_endpoint時,Microsoft身分識別平台會從瀏覽器中清除使用者的工作階段。
不過,使用者可能仍然登入其他使用Microsoft帳戶進行驗證的應用程式。
為了讓那些應用程式能同時將使用者登出,Microsoft身分識別平台會將HTTPGET要求傳送至使用者目前登入之所有應用程式的已註冊LogoutUrl。
應用程式必須藉由清除任何可識別使用者的工作階段並傳回200回應,以回應此要求。
如果您想要在應用程式中支援單一登出,您必須在應用程式的程式碼中實作這類LogoutUrl。
您可以從應用程式註冊入口網站設定LogoutUrl。
後續步驟
檢閱UserInfo文件
了解如何使用內部部署系統中的資料自訂權杖中的值。
了解如何將其他標準宣告包含在權杖中。
本文內容
延伸文章資訊
- 1Control user access using OpenID Connect - AppSheet Help
You can use any authentication provider that supports the standard OpenID Connect protocol to con...
- 2What is OpenID? | OpenID
OpenID allows you to use an existing account to sign in to multiple websites, without needing to ...
- 3OpenID Connect 是什麼? | HENNGE Taiwan 部落格
Authorization Server 的新稱呼為OpenID Provider,它除了可以發放Access Token 外,同時也可以發放ID Token。 OpenID Connect 的...
- 4OpenID Connect | Google Identity
The implicit flow is used when a client-side application (typically a JavaScript app running in t...
- 5從Azure AD 應用程式資源庫設定OpenID Connect OAuth 應用 ...
移至[企業應用程式] >[所有應用程式] 。 The Enterprise applications blade. 選取對話方塊頂端的[新增應用程式] 。 The New application...